X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fqla2xxx%2Fqla_os.c;h=cf3b81211e924cc6d6a69947327980571701cbe0;hb=ef1d465b627b9aae1124eea2d961027107b39c73;hp=788aa7a1495c04c8a5087c1e989962d36e4f32e2;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 788aa7a14..cf3b81211 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -168,7 +168,6 @@ static struct scsi_host_template qla2x00_driver_template = { .slave_configure = qla2xxx_slave_configure, .this_id = -1, - .can_queue = REQUEST_ENTRY_CNT+128, .cmd_per_lun = 3, .use_clustering = ENABLE_CLUSTERING, .sg_tablesize = SG_ALL, @@ -776,10 +775,13 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) /* Only modify the allowed count if the target is a *non* tape device */ if ((fcport->flags & FCF_TAPE_PRESENT) == 0) { + sp->flags &= ~SRB_TAPE; if (cmd->allowed < ql2xretrycount) { cmd->allowed = ql2xretrycount; } - } + } else + sp->flags |= SRB_TAPE; + DEBUG5(printk("scsi(%ld:%2d:%2d): (queuecmd) queue sp = %p, " "flags=0x%x fo retry=%d, pid=%ld\n", @@ -808,7 +810,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) atomic_read(&ha2->loop_state) == LOOP_DEAD) { /* * Add the command to the done-queue for later failover - * processing + * processing. */ cmd->result = DID_NO_CONNECT << 16; if (atomic_read(&ha2->loop_state) == LOOP_DOWN) @@ -822,7 +824,8 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) spin_lock_irq(ha->host->host_lock); return (0); } - if (tq && test_bit(TQF_SUSPENDED, &tq->flags)) { + if (tq && test_bit(TQF_SUSPENDED, &tq->flags) && + (sp->flags & SRB_TAPE) == 0) { /* If target suspended put incoming I/O in retry_q. */ qla2x00_extend_timeout(sp->cmd, 10); add_to_scsi_retry_queue(ha, sp); @@ -834,7 +837,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) device_reg_t *reg; reg = ha->iobase; - if (RD_REG_WORD(ISP_RSP_Q_IN(ha, reg)) != ha->rsp_ring_index) { + if (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) { spin_lock_irqsave(&ha->hardware_lock, flags); qla2x00_process_response_queue(ha); spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -914,7 +917,7 @@ qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) spin_unlock_irq(ha->host->host_lock); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(2*HZ); spin_lock_irq(ha->host->host_lock); @@ -962,7 +965,7 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) && time_before(jiffies, wait_online)) { - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ); } if (ha->flags.online == TRUE) @@ -1005,7 +1008,7 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) atomic_read(&ha->loop_state) == LOOP_DOWN) || test_bit(CFG_ACTIVE, &ha->cfg_flags) || atomic_read(&ha->loop_state) != LOOP_READY) { - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ); if (time_after_eq(jiffies, loop_timeout)) { return_status = QLA_FUNCTION_FAILED; @@ -1783,10 +1786,9 @@ qla2xxx_slave_configure(struct scsi_device *sdev) queue_depth = 32; if (sdev->tagged_supported) { -#if defined(MODULE) - if (!(ql2xmaxqdepth == 0 || ql2xmaxqdepth > 256)) + if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU) queue_depth = ql2xmaxqdepth; -#endif + ql2xmaxqdepth = queue_depth; scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); @@ -1983,19 +1985,24 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) if (IS_QLA2100(ha)) { ha->max_targets = MAX_TARGETS_2100; ha->mbx_count = MAILBOX_REGISTER_COUNT_2100; + ha->request_q_length = REQUEST_ENTRY_CNT_2100; ha->response_q_length = RESPONSE_ENTRY_CNT_2100; ha->last_loop_id = SNS_LAST_LOOP_ID_2100; + host->sg_tablesize = 32; } else if (IS_QLA2200(ha)) { ha->max_targets = MAX_TARGETS_2200; ha->mbx_count = MAILBOX_REGISTER_COUNT; + ha->request_q_length = REQUEST_ENTRY_CNT_2200; ha->response_q_length = RESPONSE_ENTRY_CNT_2100; ha->last_loop_id = SNS_LAST_LOOP_ID_2100; } else /*if (IS_QLA2300(ha))*/ { ha->max_targets = MAX_TARGETS_2200; ha->mbx_count = MAILBOX_REGISTER_COUNT; + ha->request_q_length = REQUEST_ENTRY_CNT_2200; ha->response_q_length = RESPONSE_ENTRY_CNT_2300; ha->last_loop_id = SNS_LAST_LOOP_ID_2300; } + host->can_queue = ha->request_q_length + 128; /* load the F/W, read paramaters, and init the H/W */ ha->instance = num_hosts; @@ -2020,6 +2027,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) spin_lock_init(&ha->mbx_reg_lock); spin_lock_init(&ha->list_lock); + ha->dpc_pid = -1; init_completion(&ha->dpc_inited); init_completion(&ha->dpc_exited); @@ -2125,8 +2133,8 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) qla2x00_check_fabric_devices(ha); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(5); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/100); } pci_set_drvdata(pdev, ha); @@ -2313,18 +2321,17 @@ qla2x00_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length, int inout) { struct info_str info; - int i; int retval = -EINVAL; os_lun_t *up; - fc_port_t *fcport; + os_tgt_t *tq; unsigned int t, l; uint32_t tmp_sn; - unsigned long *flags; + uint32_t *flags; uint8_t *loop_state; int found; scsi_qla_host_t *ha; char fw_info[30]; - + DEBUG3(printk(KERN_INFO "Entering proc_info buff_in=%p, offset=0x%lx, length=0x%x\n", buffer, offset, length);) @@ -2390,8 +2397,8 @@ qla2x00_proc_info(struct Scsi_Host *shost, char *buffer, (unsigned long long)ha->response_dma); copy_info(&info, - "Request Queue count = %ld, Response Queue count = %ld\n", - (long)REQUEST_ENTRY_CNT, (long)ha->response_q_length); + "Request Queue count = %d, Response Queue count = %d\n", + ha->request_q_length, ha->response_q_length); copy_info(&info, "Total number of active commands = %ld\n", @@ -2428,7 +2435,7 @@ qla2x00_proc_info(struct Scsi_Host *shost, char *buffer, ha->done_q_cnt, ha->scsi_retry_q_cnt); - flags = (unsigned long *) &ha->flags; + flags = (uint32_t *) &ha->flags; if (atomic_read(&ha->loop_state) == LOOP_DOWN) { loop_state = "DOWN"; @@ -2502,24 +2509,19 @@ qla2x00_proc_info(struct Scsi_Host *shost, char *buffer, ha->init_cb->port_name[7]); /* Print out device port names */ - i = 0; - list_for_each_entry(fcport, &ha->fcports, list) { - if (fcport->port_type != FCT_TARGET) + for (t = 0; t < MAX_FIBRE_DEVICES; t++) { + if ((tq = TGT_Q(ha, t)) == NULL) continue; copy_info(&info, "scsi-qla%d-target-%d=" - "%02x%02x%02x%02x%02x%02x%02x%02x:%02x%02x%02x;\n", - (int)ha->instance, i, - fcport->port_name[0], fcport->port_name[1], - fcport->port_name[2], fcport->port_name[3], - fcport->port_name[4], fcport->port_name[5], - fcport->port_name[6], fcport->port_name[7], - fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa); - i++; + "%02x%02x%02x%02x%02x%02x%02x%02x;\n", + (int)ha->instance, t, + tq->port_name[0], tq->port_name[1], + tq->port_name[2], tq->port_name[3], + tq->port_name[4], tq->port_name[5], + tq->port_name[6], tq->port_name[7]); } - copy_info(&info, "\nSCSI LUN Information:\n"); copy_info(&info, "(Id:Lun) * - indicates lun is not registered with the OS.\n"); @@ -2861,14 +2863,14 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) * little delay and a retry. */ ha->request_ring = pci_alloc_consistent(ha->pdev, - ((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))), + ((ha->request_q_length + 1) * (sizeof(request_t))), &ha->request_dma); if (ha->request_ring == NULL) { qla_printk(KERN_WARNING, ha, "Memory Allocation failed - request_ring\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; @@ -2882,7 +2884,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "Memory Allocation failed - response_ring\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; @@ -2896,7 +2898,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "Memory Allocation failed - init_cb\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; @@ -2909,7 +2911,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "Memory Allocation failed - ioctl_mem\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; @@ -2921,14 +2923,14 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "qla2x00_allocate_sp_pool()\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; } /* Allocate memory for SNS commands */ - if (IS_QLA2200(ha)) { + if (IS_QLA2100(ha) || IS_QLA2200(ha)) { /* Get consistent memory allocated for SNS commands */ ha->sns_cmd = pci_alloc_consistent(ha->pdev, sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma); @@ -2938,13 +2940,13 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "Memory Allocation failed - sns_cmd\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; } memset(ha->sns_cmd, 0, sizeof(struct sns_cmd_pkt)); - } else if (!IS_QLA2100(ha)) { + } else { /* Get consistent memory allocated for MS IOCB */ ha->ms_iocb = pci_alloc_consistent(ha->pdev, sizeof(ms_iocb_entry_t), &ha->ms_iocb_dma); @@ -2954,7 +2956,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "Memory Allocation failed - ms_iocb\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; @@ -2973,7 +2975,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "Memory Allocation failed - ct_sns\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; @@ -2990,7 +2992,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "Memory Allocation failed - iodesc_pd\n"); qla2x00_mem_free(ha); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/10); continue; @@ -3077,7 +3079,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha) if (ha->request_ring) { pci_free_consistent(ha->pdev, - ((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))), + ((ha->request_q_length + 1) * (sizeof(request_t))), ha->request_ring, ha->request_dma); } @@ -3852,6 +3854,8 @@ qla2x00_timer(scsi_qla_host_t *ha) DEBUG(printk("scsi(%ld): Loop down - " "aborting ISP.\n", ha->host_no)); + qla_printk(KERN_WARNING, ha, + "Loop down - aborting ISP.\n"); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); } @@ -3936,8 +3940,8 @@ qla2x00_cmd_timeout(srb_t *sp) int processed; scsi_qla_host_t *vis_ha, *dest_ha; struct scsi_cmnd *cmd; - ulong flags; - fc_port_t *fcport; + unsigned long flags, cpu_flags; + fc_port_t *fcport; cmd = sp->cmd; vis_ha = (scsi_qla_host_t *)cmd->device->host->hostdata; @@ -4032,6 +4036,64 @@ qla2x00_cmd_timeout(srb_t *sp) return; } + spin_lock_irqsave(&dest_ha->list_lock, cpu_flags); + if (sp->state == SRB_DONE_STATE) { + /* IO in done_q -- leave it */ + DEBUG(printk("scsi(%ld): Found in Done queue pid %ld sp=%p.\n", + dest_ha->host_no, cmd->serial_number, sp)); + } else if (sp->state == SRB_SUSPENDED_STATE) { + DEBUG(printk("scsi(%ld): Found SP %p in suspended state " + "- pid %ld:\n", + dest_ha->host_no, sp, cmd->serial_number)); + DEBUG(qla2x00_dump_buffer((uint8_t *)sp, sizeof(srb_t));) + } else if (sp->state == SRB_ACTIVE_STATE) { + /* + * IO is with ISP find the command in our active list. + */ + spin_unlock_irqrestore(&dest_ha->list_lock, cpu_flags); + spin_lock_irqsave(&dest_ha->hardware_lock, flags); + if (sp == dest_ha->outstanding_cmds[ + (unsigned long)sp->cmd->host_scribble]) { + + DEBUG(printk("cmd_timeout: Found in ISP \n")); + + if (sp->flags & SRB_TAPE) { + /* + * We cannot allow the midlayer error handler + * to wakeup and begin the abort process. + * Extend the timer so that the firmware can + * properly return the IOCB. + */ + DEBUG(printk("cmd_timeout: Extending timeout " + "of FCP2 tape command!\n")); + qla2x00_extend_timeout(sp->cmd, + EXTEND_CMD_TIMEOUT); + } + sp->state = SRB_ACTIVE_TIMEOUT_STATE; + spin_unlock_irqrestore(&dest_ha->hardware_lock, flags); + } else { + spin_unlock_irqrestore(&dest_ha->hardware_lock, flags); + printk(KERN_INFO + "qla_cmd_timeout: State indicates it is with " + "ISP, But not in active array\n"); + } + spin_lock_irqsave(&dest_ha->list_lock, cpu_flags); + } else if (sp->state == SRB_ACTIVE_TIMEOUT_STATE) { + DEBUG(printk("qla2100%ld: Found in Active timeout state" + "pid %ld, State = %x., \n", + dest_ha->host_no, + sp->cmd->serial_number, sp->state);) + } else { + /* EMPTY */ + DEBUG2(printk("cmd_timeout%ld: LOST command state = " + "0x%x, sp=%p\n", + vis_ha->host_no, sp->state,sp);) + + qla_printk(KERN_INFO, vis_ha, + "cmd_timeout: LOST command state = 0x%x\n", sp->state); + } + spin_unlock_irqrestore(&dest_ha->list_lock, cpu_flags); + DEBUG3(printk("cmd_timeout: Leaving\n");) } @@ -4180,9 +4242,6 @@ qla2x00_process_response_queue_in_zio_mode(scsi_qla_host_t *ha) spin_lock_irqsave(&ha->hardware_lock,flags); qla2x00_process_response_queue(ha); spin_unlock_irqrestore(&ha->hardware_lock, flags); - - if (!list_empty(&ha->done_queue)) - qla2x00_done(ha); } /* @@ -4261,7 +4320,7 @@ qla2x00_next(scsi_qla_host_t *vis_ha) * continues until the LOOP DOWN time expires or the condition * goes away. */ - if (!(sp->flags & SRB_IOCTL) && + if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) && (atomic_read(&fcport->state) != FCS_ONLINE || test_bit(ABORT_ISP_ACTIVE, &dest_ha->dpc_flags) || atomic_read(&dest_ha->loop_state) != LOOP_READY)) { @@ -4286,7 +4345,7 @@ qla2x00_next(scsi_qla_host_t *vis_ha) * If this request's lun is suspended then put the request on * the scsi_retry queue. */ - if (!(sp->flags & SRB_IOCTL) && + if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) && sp->lun_queue->q_state == LUN_STATE_WAIT) { DEBUG3(printk("scsi(%ld): lun wait state - pid=%ld, " "opcode=%d, allowed=%d, retries=%d\n",