static __inline int ips_morpheus_check_intr(ips_softc_t *sc) { int cmdnumber; ips_cmd_status_t status; ips_command_t *command; int found = 0; u_int32_t oisr; oisr = ips_read_4(sc, MORPHEUS_REG_OISR); PRINTF(9, "interrupt registers out:%x\n", oisr); if(!(oisr & MORPHEUS_BIT_CMD_IRQ)){ DEVICE_PRINTF(2,sc->dev, "got a non-command irq\n"); return (0); } while((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR)) != 0xffffffff){ cmdnumber = status.fields.command_id; command = &sc->commandarray[cmdnumber]; command->status.value = status.value; command->timeout = 0; command->callback(command); found = 1; } return (found); }
void ips_morpheus_intr(void *void_sc) { ips_softc_t *sc = (ips_softc_t *)void_sc; u_int32_t oisr, iisr; int cmdnumber; ips_cmd_status_t status; iisr =ips_read_4(sc, MORPHEUS_REG_IISR); oisr =ips_read_4(sc, MORPHEUS_REG_OISR); PRINTF(9,"interrupt registers in:%x out:%x\n",iisr, oisr); if(!(oisr & MORPHEUS_BIT_CMD_IRQ)){ DEVICE_PRINTF(2,sc->dev, "got a non-command irq\n"); return; } while((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR)) != 0xffffffff){ cmdnumber = status.fields.command_id; sc->commandarray[cmdnumber].status.value = status.value; sc->commandarray[cmdnumber].timeout = 0; sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber])); DEVICE_PRINTF(9,sc->dev, "got command %d\n", cmdnumber); } return; }
/* see if we should reinitialize the card and wait for it to timeout or complete initialization */ int ips_morpheus_reinit(ips_softc_t *sc, int force) { u_int32_t tmp; int i; tmp = ips_read_4(sc, MORPHEUS_REG_OISR); if(!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) && (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp){ ips_write_4(sc, MORPHEUS_REG_OIMR, 0); return 0; } ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff); ips_read_4(sc, MORPHEUS_REG_OIMR); device_printf(sc->dev, "resetting adapter, this may take up to 5 minutes\n"); ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000); DELAY(5000000); ips_read_4(sc, MORPHEUS_REG_OIMR); tmp = ips_read_4(sc, MORPHEUS_REG_OISR); for(i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++){ DELAY(1000000); DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i); tmp = ips_read_4(sc, MORPHEUS_REG_OISR); } if(tmp & MORPHEUS_BIT_POST1) ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1); if( i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK){ device_printf(sc->dev,"Adapter error during initialization.\n"); return 1; } for(i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++){ DELAY(1000000); DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i); tmp = ips_read_4(sc, MORPHEUS_REG_OISR); } if(tmp & MORPHEUS_BIT_POST2) ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2); if(i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)){ device_printf(sc->dev, "adapter failed config check\n"); return 1; } ips_write_4(sc, MORPHEUS_REG_OIMR, 0); if(force && ips_clear_adapter(sc)){ device_printf(sc->dev, "adapter clear failed\n"); return 1; } return 0; }
void ips_issue_copperhead_cmd(ips_command_t *command) { int i; intrmask_t mask = splbio(); /* hmmm, is there a cleaner way to do this? */ if(command->sc->state & IPS_OFFLINE){ splx(mask); command->status.value = IPS_ERROR_STATUS; command->callback(command); return; } command->timeout = 10; for(i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT; i++ ){ if( i == 20){ printf("sem bit still set, can't send a command\n"); splx(mask); return; } DELAY(500);/* need to do a delay here */ } ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr); ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START); splx(mask); }