From a4576b5da671563187ac388e36e1d077bd20e43a Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 30 Apr 2008 15:47:35 -0400 Subject: [PATCH] [SCSI] aacraid: Fix jbod operations scan issues As JBOD devices (really just Simple Single Drive Volumes exported to the SCSI channel) are managed, they fail to update correctly when the driver triggers a SCSI scan. In addition, the ability to change multiple arrays or JBODs at the same time was resulting in dropped scans, set up a mechanism to issue a list of single target scans on a single configuration change notification from the Firmware. Performed some additional sundry cosmetic code style cleanups. Signed-off-by: Mark Salyzyn Signed-off-by: James Bottomley --- drivers/scsi/aacraid/commsup.c | 32 +++++++++++++++++++++++++------- drivers/scsi/aacraid/linit.c | 16 +++++++++------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index e7a4c6f202d..289304aab69 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -906,15 +906,22 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) case AifEnAddJBOD: case AifEnDeleteJBOD: container = le32_to_cpu(((__le32 *)aifcmd->data)[1]); - if ((container >> 28)) + if ((container >> 28)) { + container = (u32)-1; break; + } channel = (container >> 24) & 0xF; - if (channel >= dev->maximum_num_channels) + if (channel >= dev->maximum_num_channels) { + container = (u32)-1; break; + } id = container & 0xFFFF; - if (id >= dev->maximum_num_physicals) + if (id >= dev->maximum_num_physicals) { + container = (u32)-1; break; + } lun = (container >> 16) & 0xFF; + container = (u32)-1; channel = aac_phys_to_logical(channel); device_config_needed = (((__le32 *)aifcmd->data)[0] == @@ -933,13 +940,18 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) case EM_DRIVE_REMOVAL: container = le32_to_cpu( ((__le32 *)aifcmd->data)[2]); - if ((container >> 28)) + if ((container >> 28)) { + container = (u32)-1; break; + } channel = (container >> 24) & 0xF; - if (channel >= dev->maximum_num_channels) + if (channel >= dev->maximum_num_channels) { + container = (u32)-1; break; + } id = container & 0xFFFF; lun = (container >> 16) & 0xFF; + container = (u32)-1; if (id >= dev->maximum_num_physicals) { /* legacy dev_t ? */ if ((0x2000 <= id) || lun || channel || @@ -1025,9 +1037,10 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) break; } + container = 0; +retry_next: if (device_config_needed == NOTHING) - for (container = 0; container < dev->maximum_num_containers; - ++container) { + for (; container < dev->maximum_num_containers; ++container) { if ((dev->fsa_dev[container].config_waiting_on == 0) && (dev->fsa_dev[container].config_needed != NOTHING) && time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) { @@ -1110,6 +1123,11 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) } if (device_config_needed == ADD) scsi_add_device(dev->scsi_host_ptr, channel, id, lun); + if (channel == CONTAINER_CHANNEL) { + container++; + device_config_needed = NOTHING; + goto retry_next; + } } static int _aac_reset_adapter(struct aac_dev *aac, int forced) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index c109f63f827..c444527ae2f 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -401,6 +401,8 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, static int aac_slave_configure(struct scsi_device *sdev) { struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; + if (aac->jbod && (sdev->type == TYPE_DISK)) + sdev->removable = 1; if ((sdev->type == TYPE_DISK) && (sdev_channel(sdev) != CONTAINER_CHANNEL) && (!aac->jbod || sdev->inq_periph_qual) && @@ -1106,7 +1108,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, aac->pdev = pdev; aac->name = aac_driver_template.name; aac->id = shost->unique_id; - aac->cardtype = index; + aac->cardtype = index; INIT_LIST_HEAD(&aac->entry); aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL); @@ -1146,19 +1148,19 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, goto out_deinit; /* - * Lets override negotiations and drop the maximum SG limit to 34 - */ + * Lets override negotiations and drop the maximum SG limit to 34 + */ if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) && (shost->sg_tablesize > 34)) { shost->sg_tablesize = 34; shost->max_sectors = (shost->sg_tablesize * 8) + 112; - } + } - if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) && + if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) && (shost->sg_tablesize > 17)) { shost->sg_tablesize = 17; shost->max_sectors = (shost->sg_tablesize * 8) + 112; - } + } error = pci_set_dma_max_seg_size(pdev, (aac->adapter_info.options & AAC_OPT_NEW_COMM) ? @@ -1174,7 +1176,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, else aac->printf_enabled = 0; - /* + /* * max channel will be the physical channels plus 1 virtual channel * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) * physical channels are address by their actual physical number+1 -- 2.41.1