📄 qlogicisp.c
字号:
if (le16_to_cpu(sts->state_flags) & SF_GOT_SENSE) memcpy(Cmnd->sense_buffer, sts->req_sense_data, sizeof(Cmnd->sense_buffer)); DEBUG_INTR(isp1020_print_status_entry(sts)); if (sts->hdr.entry_type == ENTRY_STATUS) Cmnd->result = isp1020_return_status(sts); else Cmnd->result = DID_ERROR << 16; outw(out_ptr, host->io_port + MBOX5); (*Cmnd->scsi_done)(Cmnd); } hostdata->res_out_ptr = out_ptr; LEAVE_INTR("isp1020_intr_handler");}static int isp1020_return_status(struct Status_Entry *sts){ int host_status = DID_ERROR;#if DEBUG_ISP1020_INTR static char *reason[] = { "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR" };#endif /* DEBUG_ISP1020_INTR */ ENTER("isp1020_return_status"); DEBUG(printk("qlogicisp : completion status = 0x%04x\n", le16_to_cpu(sts->completion_status))); switch(le16_to_cpu(sts->completion_status)) { case CS_COMPLETE: host_status = DID_OK; break; case CS_INCOMPLETE: if (!(le16_to_cpu(sts->state_flags) & SF_GOT_BUS)) host_status = DID_NO_CONNECT; else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_TARGET)) host_status = DID_BAD_TARGET; else if (!(le16_to_cpu(sts->state_flags) & SF_SENT_CDB)) host_status = DID_ERROR; else if (!(le16_to_cpu(sts->state_flags) & SF_TRANSFERRED_DATA)) host_status = DID_ERROR; else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_STATUS)) host_status = DID_ERROR; else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_SENSE)) host_status = DID_ERROR; break; case CS_DMA_ERROR: case CS_TRANSPORT_ERROR: host_status = DID_ERROR; break; case CS_RESET_OCCURRED: host_status = DID_RESET; break; case CS_ABORTED: host_status = DID_ABORT; break; case CS_TIMEOUT: host_status = DID_TIME_OUT; break; case CS_DATA_OVERRUN: case CS_COMMAND_OVERRUN: case CS_STATUS_OVERRUN: case CS_BAD_MESSAGE: case CS_NO_MESSAGE_OUT: case CS_EXT_ID_FAILED: case CS_IDE_MSG_FAILED: case CS_ABORT_MSG_FAILED: case CS_NOP_MSG_FAILED: case CS_PARITY_ERROR_MSG_FAILED: case CS_DEVICE_RESET_MSG_FAILED: case CS_ID_MSG_FAILED: case CS_UNEXP_BUS_FREE: host_status = DID_ERROR; break; case CS_DATA_UNDERRUN: host_status = DID_OK; break; default: printk("qlogicisp : unknown completion status 0x%04x\n", le16_to_cpu(sts->completion_status)); host_status = DID_ERROR; break; } DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n", reason[host_status], le16_to_cpu(sts->scsi_status))); LEAVE("isp1020_return_status"); return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16);}int isp1020_abort(Scsi_Cmnd *Cmnd){ u_short param[6]; struct Scsi_Host *host; struct isp1020_hostdata *hostdata; int return_status = SCSI_ABORT_SUCCESS; u_int cmdaddr = virt_to_bus(Cmnd); ENTER("isp1020_abort"); host = Cmnd->host; hostdata = (struct isp1020_hostdata *) host->hostdata; isp1020_disable_irqs(host); param[0] = MBOX_ABORT; param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun; param[2] = cmdaddr >> 16; param[3] = cmdaddr & 0xffff; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { printk("qlogicisp : scsi abort failure: %x\n", param[0]); return_status = SCSI_ABORT_ERROR; } isp1020_enable_irqs(host); LEAVE("isp1020_abort"); return return_status;}int isp1020_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags){ u_short param[6]; struct Scsi_Host *host; struct isp1020_hostdata *hostdata; int return_status = SCSI_RESET_SUCCESS; ENTER("isp1020_reset"); host = Cmnd->host; hostdata = (struct isp1020_hostdata *) host->hostdata; param[0] = MBOX_BUS_RESET; param[1] = hostdata->host_param.bus_reset_delay; isp1020_disable_irqs(host); isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { printk("qlogicisp : scsi bus reset failure: %x\n", param[0]); return_status = SCSI_RESET_ERROR; } isp1020_enable_irqs(host); LEAVE("isp1020_reset"); return return_status;;}int isp1020_biosparam(Disk *disk, kdev_t n, int ip[]){ int size = disk->capacity; ENTER("isp1020_biosparam"); ip[0] = 64; ip[1] = 32; ip[2] = size >> 11; if (ip[2] > 1024) { ip[0] = 255; ip[1] = 63; ip[2] = size / (ip[0] * ip[1]);#if 0 if (ip[2] > 1023) ip[2] = 1023;#endif } LEAVE("isp1020_biosparam"); return 0;}static int isp1020_reset_hardware(struct Scsi_Host *host){ u_short param[6]; int loop_count; ENTER("isp1020_reset_hardware"); outw(ISP_RESET, host->io_port + PCI_INTF_CTL); udelay(100); outw(HCCR_RESET, host->io_port + HOST_HCCR); udelay(100); outw(HCCR_RELEASE, host->io_port + HOST_HCCR); outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR); loop_count = DEFAULT_LOOP_COUNT; while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY) barrier(); if (!loop_count) printk("qlogicisp: reset_hardware loop timeout\n"); outw(0, host->io_port + ISP_CFG1);#if DEBUG_ISP1020 printk("qlogicisp : mbox 0 0x%04x \n", inw(host->io_port + MBOX0)); printk("qlogicisp : mbox 1 0x%04x \n", inw(host->io_port + MBOX1)); printk("qlogicisp : mbox 2 0x%04x \n", inw(host->io_port + MBOX2)); printk("qlogicisp : mbox 3 0x%04x \n", inw(host->io_port + MBOX3)); printk("qlogicisp : mbox 4 0x%04x \n", inw(host->io_port + MBOX4)); printk("qlogicisp : mbox 5 0x%04x \n", inw(host->io_port + MBOX5));#endif /* DEBUG_ISP1020 */ param[0] = MBOX_NO_OP; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { printk("qlogicisp : NOP test failed\n"); return 1; } DEBUG(printk("qlogicisp : loading risc ram\n"));#if RELOAD_FIRMWARE for (loop_count = 0; loop_count < risc_code_length01; loop_count++) { param[0] = MBOX_WRITE_RAM_WORD; param[1] = risc_code_addr01 + loop_count; param[2] = risc_code01[loop_count]; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { printk("qlogicisp : firmware load failure at %d\n", loop_count); return 1; } }#endif /* RELOAD_FIRMWARE */ DEBUG(printk("qlogicisp : verifying checksum\n")); param[0] = MBOX_VERIFY_CHECKSUM; param[1] = risc_code_addr01; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { printk("qlogicisp : ram checksum failure\n"); return 1; } DEBUG(printk("qlogicisp : executing firmware\n")); param[0] = MBOX_EXEC_FIRMWARE; param[1] = risc_code_addr01; isp1020_mbox_command(host, param); param[0] = MBOX_ABOUT_FIRMWARE; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { printk("qlogicisp : about firmware failure\n"); return 1; } DEBUG(printk("qlogicisp : firmware major revision %d\n", param[1])); DEBUG(printk("qlogicisp : firmware minor revision %d\n", param[2])); LEAVE("isp1020_reset_hardware"); return 0;}static int isp1020_init(struct Scsi_Host *sh){ u_long io_base; struct isp1020_hostdata *hostdata; u_char revision; u_int irq; u_short command; struct pci_dev *pdev; ENTER("isp1020_init"); hostdata = (struct isp1020_hostdata *) sh->hostdata; pdev = hostdata->pci_dev; if (pci_read_config_word(pdev, PCI_COMMAND, &command) || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) { printk("qlogicisp : error reading PCI configuration\n"); return 1; } io_base = pdev->base_address[0]; irq = pdev->irq; if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) { printk("qlogicisp : 0x%04x is not QLogic vendor ID\n", pdev->vendor); return 1; } if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP1020) { printk("qlogicisp : 0x%04x does not match ISP1020 device id\n", pdev->device); return 1; }#ifdef __sparc__ command |= (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY| PCI_COMMAND_INVALIDATE|PCI_COMMAND_SERR); pci_write_config_word(pdev, PCI_COMMAND, command); pci_read_config_word(pdev, PCI_COMMAND, &command); pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 16); { unsigned char min_gnt, latency_timer; pci_read_config_byte(pdev, PCI_MIN_GNT, &min_gnt); if (min_gnt == 0) latency_timer = 64; else latency_timer = ((min_gnt << 3) & 0xff); pci_write_config_byte(pdev, PCI_LATENCY_TIMER, latency_timer); }#endif if (command & PCI_COMMAND_IO && (io_base & 3) == 1) io_base &= PCI_BASE_ADDRESS_IO_MASK; else { printk("qlogicisp : i/o mapping is disabled\n"); return 1; } if (!(command & PCI_COMMAND_MASTER)) { printk("qlogicisp : bus mastering is disabled\n"); return 1; } if (revision != ISP1020_REV_ID) printk("qlogicisp : new isp1020 revision ID (%d)\n", revision); if (inw(io_base + PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC || inw(io_base + PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020) { printk("qlogicisp : can't decode i/o address space 0x%lx\n", io_base); return 1; } hostdata->revision = revision; sh->irq = irq; sh->io_port = io_base; sh->max_id = MAX_TARGETS; sh->max_lun = MAX_LUNS; LEAVE("isp1020_init"); return 0;}#if USE_NVRAM_DEFAULTSstatic int isp1020_get_defaults(struct Scsi_Host *host){ int i; u_short value; struct isp1020_hostdata *hostdata = (struct isp1020_hostdata *) host->hostdata; ENTER("isp1020_get_defaults"); if (!isp1020_verify_nvram(host)) { printk("qlogicisp : nvram checksum failure\n"); printk("qlogicisp : attempting to use default parameters\n"); return isp1020_set_defaults(host); } value = isp1020_read_nvram_word(host, 2); hostdata->host_param.fifo_threshold = (value >> 8) & 0x03; hostdata->host_param.host_adapter_enable = (value >> 11) & 0x01; hostdata->host_param.initiator_scsi_id = (value >> 12) & 0x0f; value = isp1020_read_nvram_word(host, 3); hostdata->host_param.bus_reset_delay = value & 0xff; hostdata->host_param.retry_count = value >> 8; value = isp1020_read_nvram_word(host, 4); hostdata->host_param.retry_delay = value & 0xff; hostdata->host_param.async_data_setup_time = (value >> 8) & 0x0f; hostdata->host_param.req_ack_active_negation = (value >> 12) & 0x01; hostdata->host_param.data_line_active_negation = (value >> 13) & 0x01; hostdata->host_param.data_dma_burst_enable = (value >> 14) & 0x01; hostdata->host_param.command_dma_burst_enable = (value >> 15); value = isp1020_read_nvram_word(host, 5); hostdata->host_param.tag_aging = value & 0xff; value = isp1020_read_nvram_word(host, 6); hostdata->host_param.selection_timeout = value & 0xffff; value = isp1020_read_nvram_word(host, 7); hostdata->host_param.max_queue_depth = value & 0xffff;#if DEBUG_ISP1020_SETUP printk("qlogicisp : fifo threshold=%d\n", hostdata->host_param.fifo_threshold); printk("qlogicisp : initiator scsi id=%d\n", hostdata->host_param.initiator_scsi_id); printk("qlogicisp : bus reset delay=%d\n", hostdata->host_param.bus_reset_delay); printk("qlogicisp : retry count=%d\n", hostdata->host_param.retry_count); printk("qlogicisp : retry delay=%d\n", hostdata->host_param.retry_delay); printk("qlogicisp : async data setup time=%d\n", hostdata->host_param.async_data_setup_time); printk("qlogicisp : req/ack active negation=%d\n", hostdata->host_param.req_ack_active_negation);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -