X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fqla2xxx%2Fqla_os.c;h=22bdb841c8e4753b85a3fb6b57aa92fbf6ff22d8;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=591f1d5a5970340320879802e5624508071cd873;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 591f1d5a5..22bdb841c 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -150,6 +151,8 @@ static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); * SCSI host template entry points */ static int qla2xxx_slave_configure(struct scsi_device * device); +static int qla2x00_queuecommand(struct scsi_cmnd *cmd, + void (*fn)(struct scsi_cmnd *)); static int qla2xxx_eh_abort(struct scsi_cmnd *); static int qla2xxx_eh_device_reset(struct scsi_cmnd *); static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); @@ -235,67 +238,6 @@ static __inline__ void sp_get(struct scsi_qla_host * ha, srb_t *sp); static __inline__ void qla2x00_delete_from_done_queue(scsi_qla_host_t *, srb_t *); -/************************************************************************** -* sp_put -* -* Description: -* Decrement reference count and call the callback if we're the last -* owner of the specified sp. Will get the host_lock before calling -* the callback. -* -* Input: -* ha - pointer to the scsi_qla_host_t where the callback is to occur. -* sp - pointer to srb_t structure to use. -* -* Returns: -* -**************************************************************************/ -static inline void -sp_put(struct scsi_qla_host * ha, srb_t *sp) -{ - if (atomic_read(&sp->ref_count) == 0) { - qla_printk(KERN_INFO, ha, - "%s(): **** SP->ref_count not zero\n", - __func__); - DEBUG2(BUG();) - - return; - } - - if (!atomic_dec_and_test(&sp->ref_count)) { - return; - } - - qla2x00_callback(ha, sp->cmd); -} - -/************************************************************************** -* sp_get -* -* Description: -* Increment reference count of the specified sp. -* -* Input: -* sp - pointer to srb_t structure to use. -* -* Returns: -* -**************************************************************************/ -static inline void -sp_get(struct scsi_qla_host * ha, srb_t *sp) -{ - atomic_inc(&sp->ref_count); - - if (atomic_read(&sp->ref_count) > 2) { - qla_printk(KERN_INFO, ha, - "%s(): **** SP->ref_count greater than two\n", - __func__); - DEBUG2(BUG();) - - return; - } -} - /* * qla2x00_callback * Returns the completed SCSI command to LINUX. @@ -366,6 +308,67 @@ qla2x00_callback(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) (*(cmd)->scsi_done)(cmd); } +/************************************************************************** +* sp_put +* +* Description: +* Decrement reference count and call the callback if we're the last +* owner of the specified sp. Will get the host_lock before calling +* the callback. +* +* Input: +* ha - pointer to the scsi_qla_host_t where the callback is to occur. +* sp - pointer to srb_t structure to use. +* +* Returns: +* +**************************************************************************/ +static inline void +sp_put(struct scsi_qla_host * ha, srb_t *sp) +{ + if (atomic_read(&sp->ref_count) == 0) { + qla_printk(KERN_INFO, ha, + "%s(): **** SP->ref_count not zero\n", + __func__); + DEBUG2(BUG();) + + return; + } + + if (!atomic_dec_and_test(&sp->ref_count)) { + return; + } + + qla2x00_callback(ha, sp->cmd); +} + +/************************************************************************** +* sp_get +* +* Description: +* Increment reference count of the specified sp. +* +* Input: +* sp - pointer to srb_t structure to use. +* +* Returns: +* +**************************************************************************/ +static inline void +sp_get(struct scsi_qla_host * ha, srb_t *sp) +{ + atomic_inc(&sp->ref_count); + + if (atomic_read(&sp->ref_count) > 2) { + qla_printk(KERN_INFO, ha, + "%s(): **** SP->ref_count greater than two\n", + __func__); + DEBUG2(BUG();) + + return; + } +} + static inline void qla2x00_delete_from_done_queue(scsi_qla_host_t *dest_ha, srb_t *sp) { @@ -395,8 +398,9 @@ static void qla2x00_rst_aen(scsi_qla_host_t *); static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *); static void qla2x00_mem_free(scsi_qla_host_t *ha); -int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha); -void qla2x00_free_sp_pool(scsi_qla_host_t *ha); +static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha); +static void qla2x00_free_sp_pool(scsi_qla_host_t *ha); +static srb_t *qla2x00_get_new_sp(scsi_qla_host_t *ha); static ssize_t qla2x00_sysfs_read_fw_dump(struct kobject *, char *, loff_t, size_t); @@ -427,13 +431,6 @@ static struct bin_attribute sysfs_nvram_attr = { .write = qla2x00_sysfs_write_nvram, }; - -int -qla2x00_set_info(char *buffer, int length, struct Scsi_Host *shost) -{ - return (-ENOSYS); /* Currently this is a no-op */ -} - /* -------------------------------------------------------------------------- */ @@ -569,6 +566,7 @@ static ssize_t qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, /* Write NVRAM. */ spin_lock_irqsave(&ha->hardware_lock, flags); qla2x00_lock_nvram_access(ha); + qla2x00_release_nvram_protection(ha); witer = (uint16_t *)buf; for (cnt = 0; cnt < count / 2; cnt++) { qla2x00_write_nvram_word(ha, cnt+ha->nvram_base, @@ -582,7 +580,7 @@ static ssize_t qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, } /* -------------------------------------------------------------------------- */ -char * +static char * qla2x00_get_pci_info_str(struct scsi_qla_host *ha, char *str) { static char *pci_bus_modes[] = { @@ -662,7 +660,7 @@ qla2x00_get_fw_version_str(struct scsi_qla_host *ha, char *str) * interrupt handler may call this routine as part of request-completion * handling). **************************************************************************/ -int +static int qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) { fc_port_t *fcport; @@ -753,7 +751,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) cmd->host_scribble = (unsigned char *)handle; /* Bookkeeping information */ - sp->r_start = jiffies; /* time the request was recieved */ + sp->r_start = jiffies; /* Time the request was recieved. */ sp->u_start = 0; /* Setup device queue pointers. */ @@ -793,7 +791,6 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) } else sp->flags |= SRB_TAPE; - DEBUG5(printk("scsi(%ld:%2d:%2d): (queuecmd) queue sp = %p, " "flags=0x%x fo retry=%d, pid=%ld\n", ha->host_no, t, l, sp, sp->flags, sp->fo_retry_cnt, @@ -835,6 +832,7 @@ 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) && (sp->flags & SRB_TAPE) == 0) { /* If target suspended put incoming I/O in retry_q. */ @@ -844,11 +842,9 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) was_empty = add_to_pending_queue(ha, sp); if ((IS_QLA2100(ha) || IS_QLA2200(ha)) && ha->flags.online) { - unsigned long flags; - device_reg_t *reg; - reg = ha->iobase; - if (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) { + unsigned long flags; + spin_lock_irqsave(&ha->hardware_lock, flags); qla2x00_process_response_queue(ha); spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -863,7 +859,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) * In all other cases we'll let an irq pick up our IO and submit it * to the controller to improve affinity. */ - if (smp_processor_id() == ha->last_irq_cpu || was_empty) + if (_smp_processor_id() == ha->last_irq_cpu || was_empty) qla2x00_next(ha); spin_lock_irq(ha->host->host_lock); @@ -957,7 +953,7 @@ qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) * Success (Adapter is online) : 0 * Failed (Adapter is offline/disabled) : 1 */ -int +static int qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) { int return_status; @@ -969,8 +965,7 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) test_bit(ISP_ABORT_RETRY, &ha->dpc_flags) || ha->dpc_active) && time_before(jiffies, wait_online)) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); + msleep(1000); } if (ha->flags.online) return_status = QLA_SUCCESS; @@ -1011,8 +1006,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_UNINTERRUPTIBLE); - schedule_timeout(HZ); + msleep(1000); if (time_after_eq(jiffies, loop_timeout)) { return_status = QLA_FUNCTION_FAILED; break; @@ -1293,7 +1287,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) * * Note: **************************************************************************/ -int +static int qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) { int cnt; @@ -1505,7 +1499,7 @@ eh_dev_reset_done: * * Note: **************************************************************************/ -int +static int qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) { int cnt; @@ -1583,14 +1577,10 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) if (rval == FAILED) goto out; - /* - * Blocking Call. It goes to sleep waiting for cmd to get to done q - * - * XXX(hch): really? We're under host_lock here.. - */ /* Waiting for our command in done_queue to be returned to OS.*/ - if (!qla2x00_eh_wait_for_pending_commands(ha)) - rval = FAILED; + if (cmd->device->host->eh_active) + if (!qla2x00_eh_wait_for_pending_commands(ha)) + rval = FAILED; out: qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, @@ -1819,28 +1809,27 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha) * assist in setting the proper dma mask. */ if (sizeof(dma_addr_t) > 4) { - /* Update our PCI device dma_mask for full 64 bits */ - if (pci_set_dma_mask(ha->pdev, 0xffffffffffffffffULL) == 0) { + if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) { ha->flags.enable_64bit_addressing = 1; ha->calc_request_entries = qla2x00_calc_iocbs_64; ha->build_scsi_iocbs = qla2x00_build_scsi_iocbs_64; if (pci_set_consistent_dma_mask(ha->pdev, - 0xffffffffffffffffULL)) { + DMA_64BIT_MASK)) { qla_printk(KERN_DEBUG, ha, "Failed to set 64 bit PCI consistent mask; " "using 32 bit.\n"); pci_set_consistent_dma_mask(ha->pdev, - 0xffffffffULL); + DMA_32BIT_MASK); } } else { qla_printk(KERN_DEBUG, ha, "Failed to set 64 bit PCI DMA mask, falling back " "to 32 bit MASK.\n"); - pci_set_dma_mask(ha->pdev, 0xffffffff); + pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK); } } else { - pci_set_dma_mask(ha->pdev, 0xffffffff); + pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK); } } @@ -1896,15 +1885,13 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) ha->pio_address = pio; ha->pio_length = pio_len; - ha->mmio_address = ioremap(mmio, MIN_IOBASE_LEN); - if (!ha->mmio_address) { + ha->iobase = ioremap(mmio, MIN_IOBASE_LEN); + if (!ha->iobase) { qla_printk(KERN_ERR, ha, "cannot remap MMIO (%s), aborting\n", ha->pdev->slot_name); goto iospace_error_exit; } - ha->mmio_length = mmio_len; - ha->iobase = (device_reg_t *) ha->mmio_address; return (0); @@ -1918,7 +1905,7 @@ iospace_error_exit: int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) { int ret; - device_reg_t *reg; + device_reg_t __iomem *reg; struct Scsi_Host *host; scsi_qla_host_t *ha; unsigned long flags = 0; @@ -1934,7 +1921,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) if (host == NULL) { printk(KERN_WARNING "qla2xxx: Couldn't allocate host from scsi layer!\n"); - return -1; + goto probe_disable_device; } /* Clear our data area */ @@ -2068,8 +2055,13 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) host->unique_id = ha->instance; host->max_id = ha->max_targets; - if (request_irq(host->irq, qla2x00_intr_handler, SA_INTERRUPT|SA_SHIRQ, - ha->brd_info->drv_name, ha)) { + if (IS_QLA2100(ha) || IS_QLA2200(ha)) + ret = request_irq(host->irq, qla2100_intr_handler, + SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); + else + ret = request_irq(host->irq, qla2300_intr_handler, + SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha); + if (ret != 0) { qla_printk(KERN_WARNING, ha, "Failed to reserve interrupt %d already in use.\n", host->irq); @@ -2120,8 +2112,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info) qla2x00_check_fabric_devices(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/100); + msleep(10); } pci_set_drvdata(pdev, ha); @@ -2158,6 +2149,9 @@ probe_failed: scsi_host_put(host); +probe_disable_device: + pci_disable_device(pdev); + return -1; } EXPORT_SYMBOL_GPL(qla2x00_probe_one); @@ -2224,12 +2218,11 @@ qla2x00_free_device(scsi_qla_host_t *ha) free_irq(ha->pdev->irq, ha); /* release io space registers */ + if (ha->iobase) + iounmap(ha->iobase); pci_release_regions(ha->pdev); -#if MEMORY_MAPPED_IO - if (ha->mmio_address) - iounmap(ha->mmio_address); -#endif + pci_disable_device(ha->pdev); } @@ -2326,7 +2319,7 @@ qla2x00_proc_info(struct Scsi_Host *shost, char *buffer, "%s: has data been written to the file. \n", __func__);) - return (qla2x00_set_info(buffer, length, shost)); + return -ENOSYS; } if (start) { @@ -2346,8 +2339,6 @@ qla2x00_proc_info(struct Scsi_Host *shost, char *buffer, copy_info(&info, "Driver version %s\n", qla2x00_version_str); - copy_info(&info, "Entry address = %p\n", qla2x00_set_info); - tmp_sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; copy_info(&info, "ISP: %s, Serial# %c%05d\n", @@ -2815,6 +2806,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) static uint8_t qla2x00_mem_alloc(scsi_qla_host_t *ha) { + char name[16]; uint8_t status = 1; int retry= 10; @@ -2825,57 +2817,105 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) * bug where available mem is not allocated until after a * little delay and a retry. */ - ha->request_ring = pci_alloc_consistent(ha->pdev, - ((ha->request_q_length + 1) * (sizeof(request_t))), - &ha->request_dma); + ha->request_ring = dma_alloc_coherent(&ha->pdev->dev, + (ha->request_q_length + 1) * sizeof(request_t), + &ha->request_dma, GFP_KERNEL); if (ha->request_ring == NULL) { qla_printk(KERN_WARNING, ha, "Memory Allocation failed - request_ring\n"); qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); continue; } - ha->response_ring = pci_alloc_consistent(ha->pdev, - ((ha->response_q_length + 1) * (sizeof(response_t))), - &ha->response_dma); + ha->response_ring = dma_alloc_coherent(&ha->pdev->dev, + (ha->response_q_length + 1) * sizeof(response_t), + &ha->response_dma, GFP_KERNEL); if (ha->response_ring == NULL) { qla_printk(KERN_WARNING, ha, "Memory Allocation failed - response_ring\n"); qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); + + continue; + } + + ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE, + &ha->gid_list_dma, GFP_KERNEL); + if (ha->gid_list == NULL) { + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - gid_list\n"); + + qla2x00_mem_free(ha); + msleep(100); + + continue; + } + + ha->rlc_rsp = dma_alloc_coherent(&ha->pdev->dev, + sizeof(rpt_lun_cmd_rsp_t), &ha->rlc_rsp_dma, GFP_KERNEL); + if (ha->rlc_rsp == NULL) { + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - rlc"); + + qla2x00_mem_free(ha); + msleep(100); + + continue; + } + + snprintf(name, sizeof(name), "qla2xxx_%ld", ha->host_no); + ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev, + DMA_POOL_SIZE, 8, 0); + if (ha->s_dma_pool == NULL) { + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - s_dma_pool\n"); + + qla2x00_mem_free(ha); + msleep(100); continue; } /* get consistent memory allocated for init control block */ - ha->init_cb = pci_alloc_consistent(ha->pdev, - sizeof(init_cb_t), &ha->init_cb_dma); + ha->init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, + &ha->init_cb_dma); if (ha->init_cb == NULL) { qla_printk(KERN_WARNING, ha, "Memory Allocation failed - init_cb\n"); qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); continue; } memset(ha->init_cb, 0, sizeof(init_cb_t)); + /* Get consistent memory allocated for Get Port Database cmd */ + ha->iodesc_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, + &ha->iodesc_pd_dma); + if (ha->iodesc_pd == NULL) { + /* error */ + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - iodesc_pd\n"); + + qla2x00_mem_free(ha); + msleep(100); + + continue; + } + memset(ha->iodesc_pd, 0, PORT_DATABASE_SIZE); + /* Allocate ioctl related memory. */ if (qla2x00_alloc_ioctl_mem(ha)) { qla_printk(KERN_WARNING, ha, "Memory Allocation failed - ioctl_mem\n"); qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); continue; } @@ -2886,8 +2926,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) "qla2x00_allocate_sp_pool()\n"); qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); continue; } @@ -2895,32 +2934,31 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) /* Allocate memory for SNS commands */ 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); + ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev, + sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, + GFP_KERNEL); if (ha->sns_cmd == NULL) { /* error */ qla_printk(KERN_WARNING, ha, "Memory Allocation failed - sns_cmd\n"); qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); continue; } memset(ha->sns_cmd, 0, sizeof(struct sns_cmd_pkt)); } 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); + ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, + &ha->ms_iocb_dma); if (ha->ms_iocb == NULL) { /* error */ qla_printk(KERN_WARNING, ha, "Memory Allocation failed - ms_iocb\n"); qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); continue; } @@ -2930,38 +2968,22 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) * Get consistent memory allocated for CT SNS * commands */ - ha->ct_sns = pci_alloc_consistent(ha->pdev, - sizeof(struct ct_sns_pkt), &ha->ct_sns_dma); + ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev, + sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, + GFP_KERNEL); if (ha->ct_sns == NULL) { /* error */ qla_printk(KERN_WARNING, ha, "Memory Allocation failed - ct_sns\n"); qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); + msleep(100); continue; } memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); } - /* Get consistent memory allocated for Get Port Database cmd */ - ha->iodesc_pd = pci_alloc_consistent(ha->pdev, - PORT_DATABASE_SIZE, &ha->iodesc_pd_dma); - if (ha->iodesc_pd == NULL) { - /* error */ - qla_printk(KERN_WARNING, ha, - "Memory Allocation failed - iodesc_pd\n"); - - qla2x00_mem_free(ha); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); - - continue; - } - memset(ha->iodesc_pd, 0, PORT_DATABASE_SIZE); - /* Done all allocations without any error. */ status = 0; @@ -3016,52 +3038,67 @@ qla2x00_mem_free(scsi_qla_host_t *ha) /* free sp pool */ qla2x00_free_sp_pool(ha); - if (ha->iodesc_pd) { - pci_free_consistent(ha->pdev, PORT_DATABASE_SIZE, - ha->iodesc_pd, ha->iodesc_pd_dma); - } + if (ha->sns_cmd) + dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), + ha->sns_cmd, ha->sns_cmd_dma); - if (ha->sns_cmd) { - pci_free_consistent(ha->pdev, - sizeof(struct sns_cmd_pkt), ha->sns_cmd, ha->sns_cmd_dma); - } + if (ha->ct_sns) + dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), + ha->ct_sns, ha->ct_sns_dma); - if (ha->ct_sns) { - pci_free_consistent(ha->pdev, - sizeof(struct ct_sns_pkt), ha->ct_sns, ha->ct_sns_dma); - } - if (ha->ms_iocb) { - pci_free_consistent(ha->pdev, - sizeof(ms_iocb_entry_t), ha->ms_iocb, ha->ms_iocb_dma); - } + if (ha->ms_iocb) + dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); - if (ha->init_cb) { - pci_free_consistent(ha->pdev, - sizeof(init_cb_t), ha->init_cb, ha->init_cb_dma); - } + if (ha->iodesc_pd) + dma_pool_free(ha->s_dma_pool, ha->iodesc_pd, ha->iodesc_pd_dma); - if (ha->request_ring) { - pci_free_consistent(ha->pdev, - ((ha->request_q_length + 1) * (sizeof(request_t))), - ha->request_ring, ha->request_dma); - } + if (ha->init_cb) + dma_pool_free(ha->s_dma_pool, ha->init_cb, ha->init_cb_dma); + + if (ha->s_dma_pool) + dma_pool_destroy(ha->s_dma_pool); + + if (ha->rlc_rsp) + dma_free_coherent(&ha->pdev->dev, + sizeof(rpt_lun_cmd_rsp_t), ha->rlc_rsp, + ha->rlc_rsp_dma); + + if (ha->gid_list) + dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, + ha->gid_list_dma); - if (ha->response_ring) { - pci_free_consistent(ha->pdev, - ((ha->response_q_length + 1) * (sizeof(response_t))), + if (ha->response_ring) + dma_free_coherent(&ha->pdev->dev, + (ha->response_q_length + 1) * sizeof(response_t), ha->response_ring, ha->response_dma); - } - ha->iodesc_pd = NULL; - ha->iodesc_pd_dma = 0; + if (ha->request_ring) + dma_free_coherent(&ha->pdev->dev, + (ha->request_q_length + 1) * sizeof(request_t), + ha->request_ring, ha->request_dma); + + ha->sns_cmd = NULL; + ha->sns_cmd_dma = 0; ha->ct_sns = NULL; + ha->ct_sns_dma = 0; ha->ms_iocb = NULL; - + ha->ms_iocb_dma = 0; + ha->iodesc_pd = NULL; + ha->iodesc_pd_dma = 0; ha->init_cb = NULL; - ha->request_ring = NULL; - ha->request_dma = 0; + ha->init_cb_dma = 0; + + ha->s_dma_pool = NULL; + + ha->rlc_rsp = NULL; + ha->rlc_rsp_dma = 0; + ha->gid_list = NULL; + ha->gid_list_dma = 0; + ha->response_ring = NULL; ha->response_dma = 0; + ha->request_ring = NULL; + ha->request_dma = 0; list_for_each_safe(fcpl, fcptemp, &ha->fcports) { fcport = list_entry(fcpl, fc_port_t, list); @@ -3080,16 +3117,15 @@ qla2x00_mem_free(scsi_qla_host_t *ha) } INIT_LIST_HEAD(&ha->fcports); - if (ha->fw_dump) { + if (ha->fw_dump) free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order); - ha->fw_dump = NULL; - } - if (ha->fw_dump_buffer) { + if (ha->fw_dump_buffer) vfree(ha->fw_dump_buffer); - ha->fw_dump_reading = 0; - ha->fw_dump_buffer = NULL; - } + + ha->fw_dump = NULL; + ha->fw_dump_reading = 0; + ha->fw_dump_buffer = NULL; } /* @@ -3105,7 +3141,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha) * * Note: Sets the ref_count for non Null sp to one. */ -int +static int qla2x00_allocate_sp_pool(scsi_qla_host_t *ha) { int rval; @@ -3124,7 +3160,7 @@ qla2x00_allocate_sp_pool(scsi_qla_host_t *ha) * This routine frees all adapter allocated memory. * */ -void +static void qla2x00_free_sp_pool( scsi_qla_host_t *ha) { if (ha->srb_mempool) { @@ -3187,9 +3223,6 @@ qla2x00_do_dpc(void *data) if (ha->dpc_should_die) break; - if (!list_empty(&ha->done_queue)) - qla2x00_done(ha); - DEBUG3(printk("qla2x00: DPC handler waking up\n")); /* Initialization not yet finished. Don't do anything yet. */ @@ -3200,6 +3233,9 @@ qla2x00_do_dpc(void *data) ha->dpc_active = 1; + if (!list_empty(&ha->done_queue)) + qla2x00_done(ha); + /* Process commands in retry queue */ if (test_and_clear_bit(PORT_RESTART_NEEDED, &ha->dpc_flags)) { DEBUG(printk("scsi(%ld): DPC checking retry_q. " @@ -3585,7 +3621,7 @@ qla2x00_rst_aen(scsi_qla_host_t *ha) * output: * srb_t * or NULL */ -srb_t * +static srb_t * qla2x00_get_new_sp(scsi_qla_host_t *ha) { srb_t *sp; @@ -3870,9 +3906,9 @@ qla2x00_cmd_timeout(srb_t *sp) if (sp->state == SRB_PENDING_STATE) { __del_from_pending_queue(vis_ha, sp); DEBUG2(printk("scsi(%ld): Found in Pending queue pid %ld, " - "State = %x., fcport state=%d jiffies=%lx\n", + "State = %x., fcport state=%d sjiffs=%lx njiffs=%lx\n", vis_ha->host_no, cmd->serial_number, sp->state, - atomic_read(&fcport->state), jiffies)); + atomic_read(&fcport->state), sp->r_start, jiffies)); /* * If FC_DEVICE is marked as dead return the cmd with @@ -3939,8 +3975,7 @@ qla2x00_cmd_timeout(srb_t *sp) if (processed) { qla2x00_done(dest_ha); - - return; + return; } spin_lock_irqsave(&dest_ha->list_lock, cpu_flags); @@ -4105,13 +4140,13 @@ qla2x00_done(scsi_qla_host_t *old_ha) default: DEBUG2(printk("scsi(%ld:%d:%d) %s: did_error " - "= %d, comp-scsi= 0x%x-0x%x.\n", + "= %d, comp-scsi= 0x%x-0x%x pid=%ld.\n", vis_ha->host_no, cmd->device->id, cmd->device->lun, __func__, host_byte(cmd->result), CMD_COMPL_STATUS(cmd), - CMD_SCSI_STATUS(cmd))); + CMD_SCSI_STATUS(cmd), cmd->serial_number)); break; } @@ -4232,11 +4267,10 @@ qla2x00_next(scsi_qla_host_t *vis_ha) test_bit(ABORT_ISP_ACTIVE, &dest_ha->dpc_flags) || atomic_read(&dest_ha->loop_state) != LOOP_READY)) { - DEBUG3(printk("scsi(%ld): port=(0x%x) retry_q(%d) " - "loop state = %d, loop counter = 0x%x dpc flags " - "= 0x%lx\n", - dest_ha->host_no, - fcport->loop_id, + DEBUG3(printk("scsi(%ld): pid=%ld port=0x%x state=%d " + "loop state=%d, loop counter=0x%x " + "dpc_flags=0x%lx\n", sp->cmd->serial_number, + dest_ha->host_no, fcport->loop_id, atomic_read(&fcport->state), atomic_read(&dest_ha->loop_state), atomic_read(&dest_ha->loop_down_timer), @@ -4286,105 +4320,6 @@ qla2x00_next(scsi_qla_host_t *vis_ha) } } - -/************************************************************************** -* qla2x00_check_tgt_status -* -* Description: -* Checks to see if the target or loop is down. -* -* Input: -* cmd - pointer to Scsi cmd structure -* -* Returns: -* 1 - if target is present -* 0 - if target is not present -* -**************************************************************************/ -int -qla2x00_check_tgt_status(scsi_qla_host_t *ha, struct scsi_cmnd *cmd) -{ - os_lun_t *lq; - unsigned int b, t, l; - fc_port_t *fcport; - - /* Generate LU queue on bus, target, LUN */ - b = cmd->device->channel; - t = cmd->device->id; - l = cmd->device->lun; - - if ((lq = GET_LU_Q(ha,t,l)) == NULL) { - return (QLA_FUNCTION_FAILED); - } - - fcport = lq->fclun->fcport; - - if (TGT_Q(ha, t) == NULL || - l >= ha->max_luns || - atomic_read(&fcport->state) == FCS_DEVICE_DEAD || - atomic_read(&ha->loop_state) == LOOP_DEAD || - (!atomic_read(&ha->loop_down_timer) && - atomic_read(&ha->loop_state) == LOOP_DOWN) || - test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || - test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || - atomic_read(&ha->loop_state) != LOOP_READY) { - - DEBUG(printk(KERN_INFO - "scsi(%ld:%2d:%2d:%2d): %s connection is down\n", - ha->host_no, - b, t, l, - __func__)); - - cmd->result = DID_NO_CONNECT << 16; - return (QLA_FUNCTION_FAILED); - } - return (QLA_SUCCESS); -} - -/************************************************************************** -* qla2x00_check_port_status -* -* Description: -* Checks to see if the port or loop is down. -* -* Input: -* fcport - pointer to fc_port_t structure. -* -* Returns: -* 1 - if port is present -* 0 - if port is not present -* -**************************************************************************/ -int -qla2x00_check_port_status(scsi_qla_host_t *ha, fc_port_t *fcport) -{ - if (fcport == NULL) { - return (QLA_FUNCTION_FAILED); - } - - if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || - atomic_read(&ha->loop_state) == LOOP_DEAD) { - return (QLA_FUNCTION_FAILED); - } - - if ((atomic_read(&fcport->state) != FCS_ONLINE) || - (!atomic_read(&ha->loop_down_timer) && - atomic_read(&ha->loop_state) == LOOP_DOWN) || - (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) || - test_bit(CFG_ACTIVE, &ha->cfg_flags) || - test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || - atomic_read(&ha->loop_state) != LOOP_READY) { - - DEBUG(printk(KERN_INFO - "scsi(%ld): Connection is down. fcport=%p.\n", - ha->host_no, fcport)); - - return (QLA_BUSY); - } - - return (QLA_SUCCESS); -} - /* XXX(hch): crude hack to emulate a down_timeout() */ int qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) @@ -4403,61 +4338,64 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout) } static void -qla2xxx_get_port_id(struct scsi_device *sdev) +qla2xxx_get_port_id(struct scsi_target *starget) { - scsi_qla_host_t *ha = to_qla_host(sdev->host); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + scsi_qla_host_t *ha = to_qla_host(shost); struct fc_port *fc; list_for_each_entry(fc, &ha->fcports, list) { - if (fc->os_target_id == sdev->id) { - fc_port_id(sdev) = fc->d_id.b.domain << 16 | + if (fc->os_target_id == starget->id) { + fc_starget_port_id(starget) = fc->d_id.b.domain << 16 | fc->d_id.b.area << 8 | fc->d_id.b.al_pa; return; } } - fc_port_id(sdev) = -1; + fc_starget_port_id(starget) = -1; } static void -qla2xxx_get_port_name(struct scsi_device *sdev) +qla2xxx_get_port_name(struct scsi_target *starget) { - scsi_qla_host_t *ha = to_qla_host(sdev->host); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + scsi_qla_host_t *ha = to_qla_host(shost); struct fc_port *fc; list_for_each_entry(fc, &ha->fcports, list) { - if (fc->os_target_id == sdev->id) { - fc_port_name(sdev) = + if (fc->os_target_id == starget->id) { + fc_starget_port_name(starget) = __be64_to_cpu(*(uint64_t *)fc->port_name); return; } } - fc_port_name(sdev) = -1; + fc_starget_port_name(starget) = -1; } static void -qla2xxx_get_node_name(struct scsi_device *sdev) +qla2xxx_get_node_name(struct scsi_target *starget) { - scsi_qla_host_t *ha = to_qla_host(sdev->host); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + scsi_qla_host_t *ha = to_qla_host(shost); struct fc_port *fc; list_for_each_entry(fc, &ha->fcports, list) { - if (fc->os_target_id == sdev->id) { - fc_node_name(sdev) = + if (fc->os_target_id == starget->id) { + fc_starget_node_name(starget) = __be64_to_cpu(*(uint64_t *)fc->node_name); return; } } - fc_node_name(sdev) = -1; + fc_starget_node_name(starget) = -1; } static struct fc_function_template qla2xxx_transport_functions = { - .get_port_id = qla2xxx_get_port_id, - .show_port_id = 1, - .get_port_name = qla2xxx_get_port_name, - .show_port_name = 1, - .get_node_name = qla2xxx_get_node_name, - .show_node_name = 1, + .get_starget_port_id = qla2xxx_get_port_id, + .show_starget_port_id = 1, + .get_starget_port_name = qla2xxx_get_port_name, + .show_starget_port_name = 1, + .get_starget_node_name = qla2xxx_get_node_name, + .show_starget_node_name = 1, }; /** @@ -4486,9 +4424,7 @@ qla2x00_module_init(void) if (!qla2xxx_transport_template) return -ENODEV; - printk(KERN_INFO - "QLogic Fibre Channel HBA Driver (%p)\n", qla2x00_set_info); - + printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); return 0; }