📄 qlogicisp.c
字号:
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); printk("qlogicisp : data line active negation=%d\n", hostdata->host_param.data_line_active_negation); printk("qlogicisp : data DMA burst enable=%d\n", hostdata->host_param.data_dma_burst_enable); printk("qlogicisp : command DMA burst enable=%d\n", hostdata->host_param.command_dma_burst_enable); printk("qlogicisp : tag age limit=%d\n", hostdata->host_param.tag_aging); printk("qlogicisp : selection timeout limit=%d\n", hostdata->host_param.selection_timeout); printk("qlogicisp : max queue depth=%d\n", hostdata->host_param.max_queue_depth);#endif /* DEBUG_ISP1020_SETUP */ for (i = 0; i < MAX_TARGETS; i++) { value = isp1020_read_nvram_word(host, 14 + i * 3); hostdata->dev_param[i].device_flags = value & 0xff; hostdata->dev_param[i].execution_throttle = value >> 8; value = isp1020_read_nvram_word(host, 15 + i * 3); hostdata->dev_param[i].synchronous_period = value & 0xff; hostdata->dev_param[i].synchronous_offset = (value >> 8) & 0x0f; hostdata->dev_param[i].device_enable = (value >> 12) & 0x01;#if DEBUG_ISP1020_SETUP printk("qlogicisp : target 0x%02x\n", i); printk("qlogicisp : device flags=0x%02x\n", hostdata->dev_param[i].device_flags); printk("qlogicisp : execution throttle=%d\n", hostdata->dev_param[i].execution_throttle); printk("qlogicisp : synchronous period=%d\n", hostdata->dev_param[i].synchronous_period); printk("qlogicisp : synchronous offset=%d\n", hostdata->dev_param[i].synchronous_offset); printk("qlogicisp : device enable=%d\n", hostdata->dev_param[i].device_enable);#endif /* DEBUG_ISP1020_SETUP */ } LEAVE("isp1020_get_defaults"); return 0;}#define ISP1020_NVRAM_LEN 0x40#define ISP1020_NVRAM_SIG1 0x5349#define ISP1020_NVRAM_SIG2 0x2050static int isp1020_verify_nvram(struct Scsi_Host *host){ int i; u_short value; u_char checksum = 0; for (i = 0; i < ISP1020_NVRAM_LEN; i++) { value = isp1020_read_nvram_word(host, i); switch (i) { case 0: if (value != ISP1020_NVRAM_SIG1) return 0; break; case 1: if (value != ISP1020_NVRAM_SIG2) return 0; break; case 2: if ((value & 0xff) != 0x02) return 0; break; } checksum += value & 0xff; checksum += value >> 8; } return (checksum == 0);}#define NVRAM_DELAY() udelay(2) /* 2 microsecond delay */u_short isp1020_read_nvram_word(struct Scsi_Host *host, u_short byte){ int i; u_short value, output, input; byte &= 0x3f; byte |= 0x0180; for (i = 8; i >= 0; i--) { output = ((byte >> i) & 0x1) ? 0x4 : 0x0; isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY(); isp_outw(output | 0x3, host, PCI_NVRAM); NVRAM_DELAY(); isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY(); } for (i = 0xf, value = 0; i >= 0; i--) { value <<= 1; isp_outw(0x3, host, PCI_NVRAM); NVRAM_DELAY(); input = isp_inw(host, PCI_NVRAM); NVRAM_DELAY(); isp_outw(0x2, host, PCI_NVRAM); NVRAM_DELAY(); if (input & 0x8) value |= 1; } isp_outw(0x0, host, PCI_NVRAM); NVRAM_DELAY(); return value;}#endif /* USE_NVRAM_DEFAULTS */static int isp1020_set_defaults(struct Scsi_Host *host){ struct isp1020_hostdata *hostdata = (struct isp1020_hostdata *) host->hostdata; int i; ENTER("isp1020_set_defaults"); hostdata->host_param.fifo_threshold = 2; hostdata->host_param.host_adapter_enable = 1; hostdata->host_param.initiator_scsi_id = 7; hostdata->host_param.bus_reset_delay = 3; hostdata->host_param.retry_count = 0; hostdata->host_param.retry_delay = 1; hostdata->host_param.async_data_setup_time = 6; hostdata->host_param.req_ack_active_negation = 1; hostdata->host_param.data_line_active_negation = 1; hostdata->host_param.data_dma_burst_enable = 1; hostdata->host_param.command_dma_burst_enable = 1; hostdata->host_param.tag_aging = 8; hostdata->host_param.selection_timeout = 250; hostdata->host_param.max_queue_depth = 256; for (i = 0; i < MAX_TARGETS; i++) { hostdata->dev_param[i].device_flags = 0xfd; hostdata->dev_param[i].execution_throttle = 16; hostdata->dev_param[i].synchronous_period = 25; hostdata->dev_param[i].synchronous_offset = 12; hostdata->dev_param[i].device_enable = 1; } LEAVE("isp1020_set_defaults"); return 0;}static int isp1020_load_parameters(struct Scsi_Host *host){ int i, k;#ifdef CONFIG_QL_ISP_A64 u_long queue_addr; u_short param[8];#else u_int queue_addr; u_short param[6];#endif u_short isp_cfg1, hwrev; unsigned long flags; struct isp1020_hostdata *hostdata = (struct isp1020_hostdata *) host->hostdata; ENTER("isp1020_load_parameters"); save_flags(flags); cli(); hwrev = isp_inw(host, ISP_CFG0) & ISP_CFG0_HWMSK; isp_cfg1 = ISP_CFG1_F64 | ISP_CFG1_BENAB; if (hwrev == ISP_CFG0_1040A) { /* Busted fifo, says mjacob. */ isp_cfg1 &= ISP_CFG1_BENAB; } isp_outw(isp_inw(host, ISP_CFG1) | isp_cfg1, host, ISP_CFG1); isp_outw(isp_inw(host, CDMA_CONF) | DMA_CONF_BENAB, host, CDMA_CONF); isp_outw(isp_inw(host, DDMA_CONF) | DMA_CONF_BENAB, host, DDMA_CONF); param[0] = MBOX_SET_INIT_SCSI_ID; param[1] = hostdata->host_param.initiator_scsi_id; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set initiator id failure\n"); return 1; } param[0] = MBOX_SET_RETRY_COUNT; param[1] = hostdata->host_param.retry_count; param[2] = hostdata->host_param.retry_delay; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set retry count failure\n"); return 1; } param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME; param[1] = hostdata->host_param.async_data_setup_time; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : async data setup time failure\n"); return 1; } param[0] = MBOX_SET_ACTIVE_NEG_STATE; param[1] = (hostdata->host_param.req_ack_active_negation << 4) | (hostdata->host_param.data_line_active_negation << 5); isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set active negation state failure\n"); return 1; } param[0] = MBOX_SET_PCI_CONTROL_PARAMS; param[1] = hostdata->host_param.data_dma_burst_enable << 1; param[2] = hostdata->host_param.command_dma_burst_enable << 1; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set pci control parameter failure\n"); return 1; } param[0] = MBOX_SET_TAG_AGE_LIMIT; param[1] = hostdata->host_param.tag_aging; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set tag age limit failure\n"); return 1; } param[0] = MBOX_SET_SELECT_TIMEOUT; param[1] = hostdata->host_param.selection_timeout; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set selection timeout failure\n"); return 1; } for (i = 0; i < MAX_TARGETS; i++) { if (!hostdata->dev_param[i].device_enable) continue; param[0] = MBOX_SET_TARGET_PARAMS; param[1] = i << 8; param[2] = hostdata->dev_param[i].device_flags << 8; param[3] = (hostdata->dev_param[i].synchronous_offset << 8) | hostdata->dev_param[i].synchronous_period; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set target parameter failure\n"); return 1; } for (k = 0; k < MAX_LUNS; k++) { param[0] = MBOX_SET_DEV_QUEUE_PARAMS; param[1] = (i << 8) | k; param[2] = hostdata->host_param.max_queue_depth; param[3] = hostdata->dev_param[i].execution_throttle; isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set device queue " "parameter failure\n"); return 1; } } } queue_addr = hostdata->res_dma;#ifdef CONFIG_QL_ISP_A64 param[0] = MBOX_CMD_INIT_RESPONSE_QUEUE_64;#else param[0] = MBOX_INIT_RES_QUEUE;#endif param[1] = RES_QUEUE_LEN + 1; param[2] = (u_short) (queue_addr >> 16); param[3] = (u_short) (queue_addr & 0xffff); param[4] = 0; param[5] = 0;#ifdef CONFIG_QL_ISP_A64 param[6] = (u_short) (queue_addr >> 48); param[7] = (u_short) (queue_addr >> 32);#endif isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set response queue failure\n"); return 1; } queue_addr = hostdata->req_dma;#ifdef CONFIG_QL_ISP_A64 param[0] = MBOX_CMD_INIT_REQUEST_QUEUE_64;#else param[0] = MBOX_INIT_REQ_QUEUE;#endif param[1] = QLOGICISP_REQ_QUEUE_LEN + 1; param[2] = (u_short) (queue_addr >> 16); param[3] = (u_short) (queue_addr & 0xffff); param[4] = 0;#ifdef CONFIG_QL_ISP_A64 param[5] = 0; param[6] = (u_short) (queue_addr >> 48); param[7] = (u_short) (queue_addr >> 32);#endif isp1020_mbox_command(host, param); if (param[0] != MBOX_COMMAND_COMPLETE) { restore_flags(flags); printk("qlogicisp : set request queue failure\n"); return 1; } restore_flags(flags); LEAVE("isp1020_load_parameters"); return 0;}/* * currently, this is only called during initialization or abort/reset, * at which times interrupts are disabled, so polling is OK, I guess... */static int isp1020_mbox_command(struct Scsi_Host *host, u_short param[]){ int loop_count; if (mbox_param[param[0]] == 0) return 1; loop_count = DEFAULT_LOOP_COUNT; while (--loop_count && isp_inw(host, HOST_HCCR) & 0x0080) barrier(); if (!loop_count) printk("qlogicisp: mbox_command loop timeout #1\n"); switch(mbox_param[param[0]] >> 4) { case 8: isp_outw(param[7], host, MBOX7); case 7: isp_outw(param[6], host, MBOX6); case 6: isp_outw(param[5], host, MBOX5); case 5: isp_outw(param[4], host, MBOX4); case 4: isp_outw(param[3], host, MBOX3); case 3: isp_outw(param[2], host, MBOX2); case 2: isp_outw(param[1], host, MBOX1); case 1: isp_outw(param[0], host, MBOX0); } isp_outw(0x0, host, PCI_SEMAPHORE); isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); isp_outw(HCCR_SET_HOST_INTR, host, HOST_HCCR); loop_count = DEFAULT_LOOP_COUNT; while (--loop_count && !(isp_inw(host, PCI_INTF_STS) & 0x04)) barrier(); if (!loop_count) printk("qlogicisp: mbox_command loop timeout #2\n"); loop_count = DEFAULT_LOOP_COUNT; while (--loop_count && isp_inw(host, MBOX0) == 0x04) barrier(); if (!loop_count) printk("qlogicisp: mbox_command loop timeout #3\n"); switch(mbox_param[param[0]] & 0xf) { case 8: param[7] = isp_inw(host, MBOX7); case 7: param[6] = isp_inw(host, MBOX6); case 6: param[5] = isp_inw(host, MBOX5); case 5: param[4] = isp_inw(host, MBOX4); case 4: param[3] = isp_inw(host, MBOX3); case 3: param[2] = isp_inw(host, MBOX2); case 2: param[1] = isp_inw(host, MBOX1); case 1: param[0] = isp_inw(host, MBOX0); } isp_outw(0x0, host, PCI_SEMAPHORE); isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); return 0;}#if DEBUG_ISP1020_INTRvoid isp1020_print_status_entry(struct Status_Entry *status){ int i; printk("qlogicisp : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n", status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags); printk("qlogicisp : scsi status = 0x%04x, completion status = 0x%04x\n", le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status)); printk("qlogicisp : state flags = 0x%04x, status flags = 0x%04x\n", le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags)); printk("qlogicisp : time = 0x%04x, request sense length = 0x%04x\n", le16_to_cpu(status->time), le16_to_cpu(status->req_sense_len)); printk("qlogicisp : residual transfer length = 0x%08x\n", le32_to_cpu(status->residual)); for (i = 0; i < le16_to_cpu(status->req_sense_len); i++) printk("qlogicisp : sense data = 0x%02x\n", status->req_sense_data[i]);}#endif /* DEBUG_ISP1020_INTR */#if DEBUG_ISP1020void isp1020_print_scsi_cmd(Scsi_Cmnd *cmd){ int i; printk("qlogicisp : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", cmd->target, cmd->lun, cmd->cmd_len); printk("qlogicisp : command = "); for (i = 0; i < cmd->cmd_len; i++) printk("0x%02x ", cmd->cmnd[i]); printk("\n");}#endif /* DEBUG_ISP1020 */static Scsi_Host_Template driver_template = QLOGICISP;#include "scsi_module.c"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -