diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 16:44:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 16:44:18 -0700 |
commit | ec7ae517537ae5c7b0b2cd7f562dfa3e7a05b954 (patch) | |
tree | e6b0c64a51a7c0aa0efd09d4f7a80872e3b1657a /drivers/scsi/libsas/sas_scsi_host.c | |
parent | 97d2eb13a019ec09cc1a7ea2d3705c0b117b3c0d (diff) | |
parent | 590134fa78fbdbe5fea78c7ae0b2c3364bc9572f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (204 commits)
[SCSI] qla4xxx: export address/port of connection (fix udev disk names)
[SCSI] ipr: Fix BUG on adapter dump timeout
[SCSI] megaraid_sas: Fix instance access in megasas_reset_timer
[SCSI] hpsa: change confusing message to be more clear
[SCSI] iscsi class: fix vlan configuration
[SCSI] qla4xxx: fix data alignment and use nl helpers
[SCSI] iscsi class: fix link local mispelling
[SCSI] iscsi class: Replace iscsi_get_next_target_id with IDA
[SCSI] aacraid: use lower snprintf() limit
[SCSI] lpfc 8.3.27: Change driver version to 8.3.27
[SCSI] lpfc 8.3.27: T10 additions for SLI4
[SCSI] lpfc 8.3.27: Fix queue allocation failure recovery
[SCSI] lpfc 8.3.27: Change algorithm for getting physical port name
[SCSI] lpfc 8.3.27: Changed worst case mailbox timeout
[SCSI] lpfc 8.3.27: Miscellanous logic and interface fixes
[SCSI] megaraid_sas: Changelog and version update
[SCSI] megaraid_sas: Add driver workaround for PERC5/1068 kdump kernel panic
[SCSI] megaraid_sas: Add multiple MSI-X vector/multiple reply queue support
[SCSI] megaraid_sas: Add support for MegaRAID 9360/9380 12GB/s controllers
[SCSI] megaraid_sas: Clear FUSION_IN_RESET before enabling interrupts
...
Diffstat (limited to 'drivers/scsi/libsas/sas_scsi_host.c')
-rw-r--r-- | drivers/scsi/libsas/sas_scsi_host.c | 145 |
1 files changed, 64 insertions, 81 deletions
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index eeba76cdf77..b2c4a773165 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -182,79 +182,56 @@ int sas_queue_up(struct sas_task *task) return 0; } -/** - * sas_queuecommand -- Enqueue a command for processing - * @parameters: See SCSI Core documentation - * - * Note: XXX: Remove the host unlock/lock pair when SCSI Core can - * call us without holding an IRQ spinlock... - */ -static int sas_queuecommand_lck(struct scsi_cmnd *cmd, - void (*scsi_done)(struct scsi_cmnd *)) - __releases(host->host_lock) - __acquires(dev->sata_dev.ap->lock) - __releases(dev->sata_dev.ap->lock) - __acquires(host->host_lock) +int sas_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) { - int res = 0; - struct domain_device *dev = cmd_to_domain_dev(cmd); - struct Scsi_Host *host = cmd->device->host; struct sas_internal *i = to_sas_internal(host->transportt); + struct domain_device *dev = cmd_to_domain_dev(cmd); + struct sas_ha_struct *sas_ha = dev->port->ha; + struct sas_task *task; + int res = 0; - spin_unlock_irq(host->host_lock); + /* If the device fell off, no sense in issuing commands */ + if (dev->gone) { + cmd->result = DID_BAD_TARGET << 16; + goto out_done; + } - { - struct sas_ha_struct *sas_ha = dev->port->ha; - struct sas_task *task; - - /* If the device fell off, no sense in issuing commands */ - if (dev->gone) { - cmd->result = DID_BAD_TARGET << 16; - scsi_done(cmd); - goto out; - } + if (dev_is_sata(dev)) { + unsigned long flags; - if (dev_is_sata(dev)) { - unsigned long flags; + spin_lock_irqsave(dev->sata_dev.ap->lock, flags); + res = ata_sas_queuecmd(cmd, dev->sata_dev.ap); + spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags); + return res; + } - spin_lock_irqsave(dev->sata_dev.ap->lock, flags); - res = ata_sas_queuecmd(cmd, dev->sata_dev.ap); - spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags); - goto out; - } + task = sas_create_task(cmd, dev, GFP_ATOMIC); + if (!task) + return SCSI_MLQUEUE_HOST_BUSY; - res = -ENOMEM; - task = sas_create_task(cmd, dev, GFP_ATOMIC); - if (!task) - goto out; + /* Queue up, Direct Mode or Task Collector Mode. */ + if (sas_ha->lldd_max_execute_num < 2) + res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); + else + res = sas_queue_up(task); - cmd->scsi_done = scsi_done; - /* Queue up, Direct Mode or Task Collector Mode. */ - if (sas_ha->lldd_max_execute_num < 2) - res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); - else - res = sas_queue_up(task); + if (res) + goto out_free_task; + return 0; - /* Examine */ - if (res) { - SAS_DPRINTK("lldd_execute_task returned: %d\n", res); - ASSIGN_SAS_TASK(cmd, NULL); - sas_free_task(task); - if (res == -SAS_QUEUE_FULL) { - cmd->result = DID_SOFT_ERROR << 16; /* retry */ - res = 0; - scsi_done(cmd); - } - goto out; - } - } -out: - spin_lock_irq(host->host_lock); - return res; +out_free_task: + SAS_DPRINTK("lldd_execute_task returned: %d\n", res); + ASSIGN_SAS_TASK(cmd, NULL); + sas_free_task(task); + if (res == -SAS_QUEUE_FULL) + cmd->result = DID_SOFT_ERROR << 16; /* retry */ + else + cmd->result = DID_ERROR << 16; +out_done: + cmd->scsi_done(cmd); + return 0; } -DEF_SCSI_QCMD(sas_queuecommand) - static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) { struct sas_task *task = TO_SAS_TASK(cmd); @@ -784,8 +761,7 @@ int sas_target_alloc(struct scsi_target *starget) return 0; } -#define SAS_DEF_QD 32 -#define SAS_MAX_QD 64 +#define SAS_DEF_QD 256 int sas_slave_configure(struct scsi_device *scsi_dev) { @@ -825,34 +801,41 @@ void sas_slave_destroy(struct scsi_device *scsi_dev) struct domain_device *dev = sdev_to_domain_dev(scsi_dev); if (dev_is_sata(dev)) - dev->sata_dev.ap->link.device[0].class = ATA_DEV_NONE; + sas_to_ata_dev(dev)->class = ATA_DEV_NONE; } -int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth, - int reason) +int sas_change_queue_depth(struct scsi_device *sdev, int depth, int reason) { - int res = min(new_depth, SAS_MAX_QD); + struct domain_device *dev = sdev_to_domain_dev(sdev); - if (reason != SCSI_QDEPTH_DEFAULT) + if (dev_is_sata(dev)) + return __ata_change_queue_depth(dev->sata_dev.ap, sdev, depth, + reason); + + switch (reason) { + case SCSI_QDEPTH_DEFAULT: + case SCSI_QDEPTH_RAMP_UP: + if (!sdev->tagged_supported) + depth = 1; + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); + break; + case SCSI_QDEPTH_QFULL: + scsi_track_queue_full(sdev, depth); + break; + default: return -EOPNOTSUPP; - - if (scsi_dev->tagged_supported) - scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev), - res); - else { - struct domain_device *dev = sdev_to_domain_dev(scsi_dev); - sas_printk("device %llx LUN %x queue depth changed to 1\n", - SAS_ADDR(dev->sas_addr), - scsi_dev->lun); - scsi_adjust_queue_depth(scsi_dev, 0, 1); - res = 1; } - return res; + return depth; } int sas_change_queue_type(struct scsi_device *scsi_dev, int qt) { + struct domain_device *dev = sdev_to_domain_dev(scsi_dev); + + if (dev_is_sata(dev)) + return -EINVAL; + if (!scsi_dev->tagged_supported) return 0; |