void qlw_update_task(void *xsc) { struct qlw_softc *sc = xsc; int bus; for (bus = 0; bus < sc->sc_numbusses; bus++) qlw_update_bus(sc, bus); }
void qlw_update_task(void *arg1, void *arg2) { struct qlw_softc *sc = arg1; int bus; for (bus = 0; bus < sc->sc_numbusses; bus++) qlw_update_bus(sc, bus); }
int qlw_attach(struct qlw_softc *sc) { struct scsibus_attach_args saa; void (*parse_nvram)(struct qlw_softc *, int); int reset_delay; int bus; task_set(&sc->sc_update_task, qlw_update_task, sc); switch (sc->sc_isp_gen) { case QLW_GEN_ISP1000: sc->sc_nvram_size = 0; break; case QLW_GEN_ISP1040: sc->sc_nvram_size = 128; sc->sc_nvram_minversion = 2; parse_nvram = qlw_parse_nvram_1040; break; case QLW_GEN_ISP1080: case QLW_GEN_ISP12160: sc->sc_nvram_size = 256; sc->sc_nvram_minversion = 1; parse_nvram = qlw_parse_nvram_1080; break; default: printf("unknown isp type\n"); return (ENXIO); } /* after reset, mbox registers 1-3 should contain the string "ISP " */ if (qlw_read_mbox(sc, 1) != 0x4953 || qlw_read_mbox(sc, 2) != 0x5020 || qlw_read_mbox(sc, 3) != 0x2020) { /* try releasing the risc processor */ qlw_host_cmd(sc, QLW_HOST_CMD_RELEASE); } qlw_host_cmd(sc, QLW_HOST_CMD_PAUSE); if (qlw_softreset(sc) != 0) { printf("softreset failed\n"); return (ENXIO); } for (bus = 0; bus < sc->sc_numbusses; bus++) qlw_init_defaults(sc, bus); if (qlw_read_nvram(sc) == 0) { for (bus = 0; bus < sc->sc_numbusses; bus++) parse_nvram(sc, bus); } #ifndef ISP_NOFIRMWARE if (sc->sc_firmware && qlw_load_firmware(sc)) { printf("firmware load failed\n"); return (ENXIO); } #endif /* execute firmware */ sc->sc_mbox[0] = QLW_MBOX_EXEC_FIRMWARE; sc->sc_mbox[1] = QLW_CODE_ORG; if (qlw_mbox(sc, 0x0003, 0x0001)) { printf("ISP couldn't exec firmware: %x\n", sc->sc_mbox[0]); return (ENXIO); } delay(250000); /* from isp(4) */ sc->sc_mbox[0] = QLW_MBOX_ABOUT_FIRMWARE; if (qlw_mbox(sc, QLW_MBOX_ABOUT_FIRMWARE_IN, QLW_MBOX_ABOUT_FIRMWARE_OUT)) { printf("ISP not talking after firmware exec: %x\n", sc->sc_mbox[0]); return (ENXIO); } /* The ISP1000 firmware we use doesn't return a version number. */ if (sc->sc_isp_gen == QLW_GEN_ISP1000 && sc->sc_firmware) { sc->sc_mbox[1] = 1; sc->sc_mbox[2] = 37; sc->sc_mbox[3] = 0; sc->sc_mbox[6] = 0; } printf("%s: firmware rev %d.%d.%d, attrs 0x%x\n", DEVNAME(sc), sc->sc_mbox[1], sc->sc_mbox[2], sc->sc_mbox[3], sc->sc_mbox[6]); /* work out how many ccbs to allocate */ sc->sc_mbox[0] = QLW_MBOX_GET_FIRMWARE_STATUS; if (qlw_mbox(sc, 0x0001, 0x0007)) { printf("couldn't get firmware status: %x\n", sc->sc_mbox[0]); return (ENXIO); } sc->sc_maxrequests = sc->sc_mbox[2]; if (sc->sc_maxrequests > 512) sc->sc_maxrequests = 512; for (bus = 0; bus < sc->sc_numbusses; bus++) { if (sc->sc_max_queue_depth[bus] > sc->sc_maxrequests) sc->sc_max_queue_depth[bus] = sc->sc_maxrequests; } /* * On some 1020/1040 variants the response queue is limited to * 256 entries. We don't really need all that many anyway. */ sc->sc_maxresponses = sc->sc_maxrequests / 2; if (sc->sc_maxresponses < 64) sc->sc_maxresponses = 64; /* We may need up to 3 request entries per SCSI command. */ sc->sc_maxccbs = sc->sc_maxrequests / 3; /* Allegedly the FIFO is busted on the 1040A. */ if (sc->sc_isp_type == QLW_ISP1040A) sc->sc_isp_config &= ~QLW_PCI_FIFO_MASK; qlw_write(sc, QLW_CFG1, sc->sc_isp_config); if (sc->sc_isp_config & QLW_BURST_ENABLE) qlw_dma_burst_enable(sc); sc->sc_mbox[0] = QLW_MBOX_SET_FIRMWARE_FEATURES; sc->sc_mbox[1] = 0; if (sc->sc_fw_features & QLW_FW_FEATURE_LVD_NOTIFY) sc->sc_mbox[1] |= QLW_FW_FEATURE_LVD_NOTIFY; if (sc->sc_mbox[1] != 0 && qlw_mbox(sc, 0x0003, 0x0001)) { printf("couldn't set firmware features: %x\n", sc->sc_mbox[0]); return (ENXIO); } sc->sc_mbox[0] = QLW_MBOX_SET_CLOCK_RATE; sc->sc_mbox[1] = sc->sc_clock; if (qlw_mbox(sc, 0x0003, 0x0001)) { printf("couldn't set clock rate: %x\n", sc->sc_mbox[0]); return (ENXIO); } sc->sc_mbox[0] = QLW_MBOX_SET_RETRY_COUNT; sc->sc_mbox[1] = sc->sc_retry_count[0]; sc->sc_mbox[2] = sc->sc_retry_delay[0]; sc->sc_mbox[6] = sc->sc_retry_count[1]; sc->sc_mbox[7] = sc->sc_retry_delay[1]; if (qlw_mbox(sc, 0x00c7, 0x0001)) { printf("couldn't set retry count: %x\n", sc->sc_mbox[0]); return (ENXIO); } sc->sc_mbox[0] = QLW_MBOX_SET_ASYNC_DATA_SETUP; sc->sc_mbox[1] = sc->sc_async_data_setup[0]; sc->sc_mbox[2] = sc->sc_async_data_setup[1]; if (qlw_mbox(sc, 0x0007, 0x0001)) { printf("couldn't set async data setup: %x\n", sc->sc_mbox[0]); return (ENXIO); } sc->sc_mbox[0] = QLW_MBOX_SET_ACTIVE_NEGATION; sc->sc_mbox[1] = sc->sc_req_ack_active_neg[0] << 5; sc->sc_mbox[1] |= sc->sc_data_line_active_neg[0] << 4; sc->sc_mbox[2] = sc->sc_req_ack_active_neg[1] << 5; sc->sc_mbox[2] |= sc->sc_data_line_active_neg[1] << 4; if (qlw_mbox(sc, 0x0007, 0x0001)) { printf("couldn't set active negation: %x\n", sc->sc_mbox[0]); return (ENXIO); } sc->sc_mbox[0] = QLW_MBOX_SET_TAG_AGE_LIMIT; sc->sc_mbox[1] = sc->sc_tag_age_limit[0]; sc->sc_mbox[2] = sc->sc_tag_age_limit[1]; if (qlw_mbox(sc, 0x0007, 0x0001)) { printf("couldn't set tag age limit: %x\n", sc->sc_mbox[0]); return (ENXIO); } sc->sc_mbox[0] = QLW_MBOX_SET_SELECTION_TIMEOUT; sc->sc_mbox[1] = sc->sc_selection_timeout[0]; sc->sc_mbox[2] = sc->sc_selection_timeout[1]; if (qlw_mbox(sc, 0x0007, 0x0001)) { printf("couldn't set selection timeout: %x\n", sc->sc_mbox[0]); return (ENXIO); } for (bus = 0; bus < sc->sc_numbusses; bus++) { if (qlw_config_bus(sc, bus)) return (ENXIO); } if (qlw_alloc_ccbs(sc)) { /* error already printed */ return (ENOMEM); } sc->sc_mbox[0] = QLW_MBOX_INIT_REQ_QUEUE; sc->sc_mbox[1] = sc->sc_maxrequests; qlw_mbox_putaddr(sc->sc_mbox, sc->sc_requests); sc->sc_mbox[4] = 0; if (qlw_mbox(sc, 0x00df, 0x0001)) { printf("couldn't init request queue: %x\n", sc->sc_mbox[0]); goto free_ccbs; } sc->sc_mbox[0] = QLW_MBOX_INIT_RSP_QUEUE; sc->sc_mbox[1] = sc->sc_maxresponses; qlw_mbox_putaddr(sc->sc_mbox, sc->sc_responses); sc->sc_mbox[5] = 0; if (qlw_mbox(sc, 0x00ef, 0x0001)) { printf("couldn't init response queue: %x\n", sc->sc_mbox[0]); goto free_ccbs; } reset_delay = 0; for (bus = 0; bus < sc->sc_numbusses; bus++) { sc->sc_mbox[0] = QLW_MBOX_BUS_RESET; sc->sc_mbox[1] = sc->sc_reset_delay[bus]; sc->sc_mbox[2] = bus; if (qlw_mbox(sc, 0x0007, 0x0001)) { printf("couldn't reset bus: %x\n", sc->sc_mbox[0]); goto free_ccbs; } sc->sc_marker_required[bus] = 1; sc->sc_update_required[bus] = 0xffff; if (sc->sc_reset_delay[bus] > reset_delay) reset_delay = sc->sc_reset_delay[bus]; } /* wait for the busses to settle */ delay(reset_delay * 1000000); /* we should be good to go now, attach scsibus */ for (bus = 0; bus < sc->sc_numbusses; bus++) { sc->sc_link[bus].adapter = &qlw_switch; sc->sc_link[bus].adapter_softc = sc; sc->sc_link[bus].adapter_target = sc->sc_initiator[bus]; sc->sc_link[bus].adapter_buswidth = QLW_MAX_TARGETS; sc->sc_link[bus].openings = sc->sc_max_queue_depth[bus]; sc->sc_link[bus].pool = &sc->sc_iopool; memset(&saa, 0, sizeof(saa)); saa.saa_sc_link = &sc->sc_link[bus]; /* config_found() returns the scsibus attached to us */ sc->sc_scsibus[bus] = (struct scsibus_softc *) config_found(&sc->sc_dev, &saa, scsiprint); qlw_update_bus(sc, bus); } sc->sc_running = 1; return(0); free_ccbs: qlw_free_ccbs(sc); return (ENXIO); }