📄 qla1280.c
字号:
default: host_status = DID_ERROR; break; }#if DEBUG_QLA1280_INTR dprintk(1, "qla1280 ISP status: host status (%s) scsi status %x\n", reason[host_status], scsi_status);#endif LEAVE("qla1280_return_status"); return (scsi_status & 0xff) | (host_status << 16);}/****************************************************************************//* QLogic ISP1280 Hardware Support Functions. *//****************************************************************************/ /* * qla2100_enable_intrs * qla2100_disable_intrs * * Input: * ha = adapter block pointer. * * Returns: * None */static inline voidqla1280_enable_intrs(struct scsi_qla_host *ha){ struct device_reg *reg; reg = ha->iobase; /* enable risc and host interrupts */ WRT_REG_WORD(®->ictrl, (ISP_EN_INT | ISP_EN_RISC)); RD_REG_WORD(®->ictrl); /* PCI Posted Write flush */ ha->flags.ints_enabled = 1;}static inline voidqla1280_disable_intrs(struct scsi_qla_host *ha){ struct device_reg *reg; reg = ha->iobase; /* disable risc and host interrupts */ WRT_REG_WORD(®->ictrl, 0); RD_REG_WORD(®->ictrl); /* PCI Posted Write flush */ ha->flags.ints_enabled = 0;}/* * qla1280_initialize_adapter * Initialize board. * * Input: * ha = adapter block pointer. * * Returns: * 0 = success */static int __devinitqla1280_initialize_adapter(struct scsi_qla_host *ha){ struct device_reg *reg; int status; int bus;#if LINUX_VERSION_CODE > 0x020500 unsigned long flags;#endif ENTER("qla1280_initialize_adapter"); /* Clear adapter flags. */ ha->flags.online = 0; ha->flags.disable_host_adapter = 0; ha->flags.reset_active = 0; ha->flags.abort_isp_active = 0; ha->flags.ints_enabled = 0;#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) if (ia64_platform_is("sn2")) { int count1, count2; int c; count1 = 3; count2 = 3; printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA " "dual channel lockup workaround\n", ha->host_no); if ((c = snia_pcibr_rrb_alloc(ha->pdev, &count1, &count2)) < 0) printk(KERN_ERR "scsi(%li): Unable to allocate SN2 " "virtual DMA channels\n", ha->host_no); else ha->flags.use_pci_vchannel = 1; driver_setup.no_nvram = 1; }#endif dprintk(1, "Configure PCI space for adapter...\n"); reg = ha->iobase; /* Insure mailbox registers are free. */ WRT_REG_WORD(®->semaphore, 0); WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); WRT_REG_WORD(®->host_cmd, HC_CLR_HOST_INT); RD_REG_WORD(®->host_cmd); if (qla1280_read_nvram(ha)) { dprintk(2, "qla1280_initialize_adapter: failed to read " "NVRAM\n"); }#if LINUX_VERSION_CODE >= 0x020500 /* * It's necessary to grab the spin here as qla1280_mailbox_command * needs to be able to drop the lock unconditionally to wait * for completion. * In 2.4 ->detect is called with the io_request_lock held. */ spin_lock_irqsave(HOST_LOCK, flags);#endif status = qla1280_load_firmware(ha); if (status) { printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n", ha->host_no); goto out; } /* Setup adapter based on NVRAM parameters. */ dprintk(1, "scsi(%ld): Configure NVRAM parameters\n", ha->host_no); qla1280_nvram_config(ha); if (ha->flags.disable_host_adapter) { status = 1; goto out; } status = qla1280_init_rings(ha); if (status) goto out; /* Issue SCSI reset, if we can't reset twice then bus is dead */ for (bus = 0; bus < ha->ports; bus++) { if (!ha->bus_settings[bus].disable_scsi_reset && qla1280_bus_reset(ha, bus) && qla1280_bus_reset(ha, bus)) ha->bus_settings[bus].scsi_bus_dead = 1; } ha->flags.online = 1; out:#if LINUX_VERSION_CODE >= 0x020500 spin_unlock_irqrestore(HOST_LOCK, flags);#endif if (status) dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n"); LEAVE("qla1280_initialize_adapter"); return status;}/* * ISP Firmware Test * Checks if present version of RISC firmware is older than * driver firmware. * * Input: * ha = adapter block pointer. * * Returns: * 0 = firmware does not need to be loaded. */static intqla1280_isp_firmware(struct scsi_qla_host *ha){ struct nvram *nv = (struct nvram *) ha->response_ring; int status = 0; /* dg 2/27 always loads RISC */ uint16_t mb[MAILBOX_REGISTER_COUNT]; ENTER("qla1280_isp_firmware"); dprintk(1, "scsi(%li): Determining if RISC is loaded\n", ha->host_no); /* Bad NVRAM data, load RISC code. */ if (!ha->nvram_valid) { ha->flags.disable_risc_code_load = 0; } else ha->flags.disable_risc_code_load = nv->cntr_flags_1.disable_loading_risc_code; if (ha->flags.disable_risc_code_load) { dprintk(3, "qla1280_isp_firmware: Telling RISC to verify " "checksum of loaded BIOS code.\n"); /* Verify checksum of loaded RISC code. */ mb[0] = MBC_VERIFY_CHECKSUM; /* mb[1] = ql12_risc_code_addr01; */ mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; if (!(status = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) { /* Start firmware execution. */ dprintk(3, "qla1280_isp_firmware: Startng F/W " "execution.\n"); mb[0] = MBC_EXECUTE_FIRMWARE; /* mb[1] = ql12_risc_code_addr01; */ mb[1] = *ql1280_board_tbl[ha->devnum].fwstart; qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]); } else printk(KERN_INFO "qla1280: RISC checksum failed.\n"); } else { dprintk(1, "qla1280: NVRAM configured to load RISC load.\n"); status = 1; } if (status) dprintk(2, "qla1280_isp_firmware: **** Load RISC code ****\n"); LEAVE("qla1280_isp_firmware"); return status;}/* * Chip diagnostics * Test chip for proper operation. * * Input: * ha = adapter block pointer. * * Returns: * 0 = success. */static intqla1280_chip_diag(struct scsi_qla_host *ha){ uint16_t mb[MAILBOX_REGISTER_COUNT]; struct device_reg *reg = ha->iobase; int status = 0; int cnt; uint16_t data; dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", ®->id_l); dprintk(1, "scsi(%ld): Verifying chip\n", ha->host_no); /* Soft reset chip and wait for it to finish. */ WRT_REG_WORD(®->ictrl, ISP_RESET); /* * We can't do a traditional PCI write flush here by reading * back the register. The card will not respond once the reset * is in action and we end up with a machine check exception * instead. Nothing to do but wait and hope for the best. * A portable pci_write_flush(pdev) call would be very useful here. */ udelay(20); data = qla1280_debounce_register(®->ictrl); /* * Yet another QLogic gem ;-( */ for (cnt = 1000000; cnt && data & ISP_RESET; cnt--) { udelay(5); data = RD_REG_WORD(®->ictrl); } if (!cnt) goto fail; /* Reset register cleared by chip reset. */ dprintk(3, "qla1280_chip_diag: reset register cleared by chip reset\n"); WRT_REG_WORD(®->cfg_1, 0); /* Reset RISC and disable BIOS which allows RISC to execute out of RAM. */ WRT_REG_WORD(®->host_cmd, HC_RESET_RISC | HC_RELEASE_RISC | HC_DISABLE_BIOS); RD_REG_WORD(®->id_l); /* Flush PCI write */ data = qla1280_debounce_register(®->mailbox0); /* * I *LOVE* this code! */ for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) { udelay(5); data = RD_REG_WORD(®->mailbox0); } if (!cnt) goto fail; /* Check product ID of chip */ dprintk(3, "qla1280_chip_diag: Checking product ID of chip\n"); if (RD_REG_WORD(®->mailbox1) != PROD_ID_1 || (RD_REG_WORD(®->mailbox2) != PROD_ID_2 && RD_REG_WORD(®->mailbox2) != PROD_ID_2a) || RD_REG_WORD(®->mailbox3) != PROD_ID_3 || RD_REG_WORD(®->mailbox4) != PROD_ID_4) { printk(KERN_INFO "qla1280: Wrong product ID = " "0x%x,0x%x,0x%x,0x%x\n", RD_REG_WORD(®->mailbox1), RD_REG_WORD(®->mailbox2), RD_REG_WORD(®->mailbox3), RD_REG_WORD(®->mailbox4)); goto fail; } /* * Enable ints early!!! */ qla1280_enable_intrs(ha); dprintk(1, "qla1280_chip_diag: Checking mailboxes of chip\n"); /* Wrap Incoming Mailboxes Test. */ mb[0] = MBC_MAILBOX_REGISTER_TEST; mb[1] = 0xAAAA; mb[2] = 0x5555; mb[3] = 0xAA55; mb[4] = 0x55AA; mb[5] = 0xA5A5; mb[6] = 0x5A5A; mb[7] = 0x2525; status = qla1280_mailbox_command(ha, 0xff, mb); if (status) goto fail; if (mb[1] != 0xAAAA || mb[2] != 0x5555 || mb[3] != 0xAA55 || mb[4] != 0x55AA || mb[5] != 0xA5A5 || mb[6] != 0x5A5A || mb[7] != 0x2525) { printk(KERN_INFO "qla1280: Failed mbox check\n"); goto fail; } dprintk(3, "qla1280_chip_diag: exiting normally\n"); return 0; fail: dprintk(2, "qla1280_chip_diag: **** FAILED ****\n"); return status;}static intqla1280_load_firmware_pio(struct scsi_qla_host *ha){ uint16_t risc_address, *risc_code_address, risc_code_size; uint16_t mb[MAILBOX_REGISTER_COUNT], i; int err; /* Load RISC code. */ risc_address = *ql1280_board_tbl[ha->devnum].fwstart; risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; for (i = 0; i < risc_code_size; i++) { mb[0] = MBC_WRITE_RAM_WORD; mb[1] = risc_address + i; mb[2] = risc_code_address[i]; err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb); if (err) { printk(KERN_ERR "scsi(%li): Failed to load firmware\n", ha->host_no); return err; } } return 0;}#define DUMP_IT_BACK 0 /* for debug of RISC loading */static intqla1280_load_firmware_dma(struct scsi_qla_host *ha){ uint16_t risc_address, *risc_code_address, risc_code_size; uint16_t mb[MAILBOX_REGISTER_COUNT], cnt; int err = 0, num, i;#if DUMP_IT_BACK uint8_t *sp, *tbuf; dma_addr_t p_tbuf; tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf); if (!tbuf) return -ENOMEM;#endif /* Load RISC code. */ risc_address = *ql1280_board_tbl[ha->devnum].fwstart; risc_code_address = ql1280_board_tbl[ha->devnum].fwcode; risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen; dprintk(1, "%s: DMA RISC code (%i) words\n", __FUNCTION__, risc_code_size); num = 0; while (risc_code_size > 0) { int warn __attribute__((unused)) = 0; cnt = 2000 >> 1; if (cnt > risc_code_size) cnt = risc_code_size; dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p)," "%d,%d(0x%x)\n", risc_code_address, cnt, num, risc_address); for(i = 0; i < cnt; i++) ((uint16_t *)ha->request_ring)[i] = c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -