aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/linit.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-15 19:51:54 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-15 19:51:54 -0400
commitbc06cffdec85d487c77109dffcd2f285bdc502d3 (patch)
treeadc6e6398243da87e66c56102840597a329183a0 /drivers/scsi/aacraid/linit.c
parentd3502d7f25b22cfc9762bf1781faa9db1bb3be2e (diff)
parent9413d7b8aa777dd1fc7db9563ce5e80d769fe7b5 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (166 commits) [SCSI] ibmvscsi: convert to use the data buffer accessors [SCSI] dc395x: convert to use the data buffer accessors [SCSI] ncr53c8xx: convert to use the data buffer accessors [SCSI] sym53c8xx: convert to use the data buffer accessors [SCSI] ppa: coding police and printk levels [SCSI] aic7xxx_old: remove redundant GFP_ATOMIC from kmalloc [SCSI] i2o: remove redundant GFP_ATOMIC from kmalloc from device.c [SCSI] remove the dead CYBERSTORMIII_SCSI option [SCSI] don't build scsi_dma_{map,unmap} for !HAS_DMA [SCSI] Clean up scsi_add_lun a bit [SCSI] 53c700: Remove printk, which triggers because of low scsi clock on SNI RMs [SCSI] sni_53c710: Cleanup [SCSI] qla4xxx: Fix underrun/overrun conditions [SCSI] megaraid_mbox: use mutex instead of semaphore [SCSI] aacraid: add 51245, 51645 and 52245 adapters to documentation. [SCSI] qla2xxx: update version to 8.02.00-k1. [SCSI] qla2xxx: add support for NPIV [SCSI] stex: use resid for xfer len information [SCSI] Add Brownie 1200U3P to blacklist [SCSI] scsi.c: convert to use the data buffer accessors ...
Diffstat (limited to 'drivers/scsi/aacraid/linit.c')
-rw-r--r--drivers/scsi/aacraid/linit.c104
1 files changed, 92 insertions, 12 deletions
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 5c487ff096c7..d76e1a8cb93a 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -39,10 +39,8 @@
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/spinlock.h> 41#include <linux/spinlock.h>
42#include <linux/dma-mapping.h>
43#include <linux/syscalls.h> 42#include <linux/syscalls.h>
44#include <linux/delay.h> 43#include <linux/delay.h>
45#include <linux/smp_lock.h>
46#include <linux/kthread.h> 44#include <linux/kthread.h>
47#include <asm/semaphore.h> 45#include <asm/semaphore.h>
48 46
@@ -223,12 +221,12 @@ static struct aac_driver_ident aac_drivers[] = {
223 { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/ 221 { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
224 { aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/ 222 { aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
225 { aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/ 223 { aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
226 { aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell PERC2/QC */ 224 { aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4, AAC_QUIRK_34SG }, /* Dell PERC2/QC */
227 { aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4, AAC_QUIRK_34SG }, /* HP NetRAID-4M */ 225 { aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4, AAC_QUIRK_34SG }, /* HP NetRAID-4M */
228 226
229 { aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */ 227 { aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */
230 { aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */ 228 { aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */
231 { aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec Catch All */ 229 { aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Catch All */
232 { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */ 230 { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */
233 { aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec NEMER/ARK Catch All */ 231 { aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec NEMER/ARK Catch All */
234}; 232};
@@ -403,10 +401,6 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
403 401
404static int aac_slave_configure(struct scsi_device *sdev) 402static int aac_slave_configure(struct scsi_device *sdev)
405{ 403{
406 if (sdev_channel(sdev) == CONTAINER_CHANNEL) {
407 sdev->skip_ms_page_8 = 1;
408 sdev->skip_ms_page_3f = 1;
409 }
410 if ((sdev->type == TYPE_DISK) && 404 if ((sdev->type == TYPE_DISK) &&
411 (sdev_channel(sdev) != CONTAINER_CHANNEL)) { 405 (sdev_channel(sdev) != CONTAINER_CHANNEL)) {
412 if (expose_physicals == 0) 406 if (expose_physicals == 0)
@@ -450,6 +444,43 @@ static int aac_slave_configure(struct scsi_device *sdev)
450 return 0; 444 return 0;
451} 445}
452 446
447/**
448 * aac_change_queue_depth - alter queue depths
449 * @sdev: SCSI device we are considering
450 * @depth: desired queue depth
451 *
452 * Alters queue depths for target device based on the host adapter's
453 * total capacity and the queue depth supported by the target device.
454 */
455
456static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
457{
458 if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
459 (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
460 struct scsi_device * dev;
461 struct Scsi_Host *host = sdev->host;
462 unsigned num = 0;
463
464 __shost_for_each_device(dev, host) {
465 if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
466 (sdev_channel(dev) == CONTAINER_CHANNEL))
467 ++num;
468 ++num;
469 }
470 if (num >= host->can_queue)
471 num = host->can_queue - 1;
472 if (depth > (host->can_queue - num))
473 depth = host->can_queue - num;
474 if (depth > 256)
475 depth = 256;
476 else if (depth < 2)
477 depth = 2;
478 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
479 } else
480 scsi_adjust_queue_depth(sdev, 0, 1);
481 return sdev->queue_depth;
482}
483
453static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg) 484static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg)
454{ 485{
455 struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; 486 struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
@@ -548,6 +579,14 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
548 ssleep(1); 579 ssleep(1);
549 } 580 }
550 printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); 581 printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
582 /*
583 * This adapter needs a blind reset, only do so for Adapters that
584 * support a register, instead of a commanded, reset.
585 */
586 if ((aac->supplement_adapter_info.SupportedOptions2 &
587 le32_to_cpu(AAC_OPTION_MU_RESET|AAC_OPTION_IGNORE_RESET)) ==
588 le32_to_cpu(AAC_OPTION_MU_RESET))
589 aac_reset_adapter(aac, 2); /* Bypass wait for command quiesce */
551 return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ 590 return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */
552} 591}
553 592
@@ -731,15 +770,21 @@ static ssize_t aac_show_bios_version(struct class_device *class_dev,
731 return len; 770 return len;
732} 771}
733 772
734static ssize_t aac_show_serial_number(struct class_device *class_dev, 773ssize_t aac_show_serial_number(struct class_device *class_dev, char *buf)
735 char *buf)
736{ 774{
737 struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; 775 struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
738 int len = 0; 776 int len = 0;
739 777
740 if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) 778 if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)
741 len = snprintf(buf, PAGE_SIZE, "%x\n", 779 len = snprintf(buf, PAGE_SIZE, "%06X\n",
742 le32_to_cpu(dev->adapter_info.serial[0])); 780 le32_to_cpu(dev->adapter_info.serial[0]));
781 if (len &&
782 !memcmp(&dev->supplement_adapter_info.MfgPcbaSerialNo[
783 sizeof(dev->supplement_adapter_info.MfgPcbaSerialNo)+2-len],
784 buf, len))
785 len = snprintf(buf, PAGE_SIZE, "%.*s\n",
786 (int)sizeof(dev->supplement_adapter_info.MfgPcbaSerialNo),
787 dev->supplement_adapter_info.MfgPcbaSerialNo);
743 return len; 788 return len;
744} 789}
745 790
@@ -755,6 +800,31 @@ static ssize_t aac_show_max_id(struct class_device *class_dev, char *buf)
755 class_to_shost(class_dev)->max_id); 800 class_to_shost(class_dev)->max_id);
756} 801}
757 802
803static ssize_t aac_store_reset_adapter(struct class_device *class_dev,
804 const char *buf, size_t count)
805{
806 int retval = -EACCES;
807
808 if (!capable(CAP_SYS_ADMIN))
809 return retval;
810 retval = aac_reset_adapter((struct aac_dev*)class_to_shost(class_dev)->hostdata, buf[0] == '!');
811 if (retval >= 0)
812 retval = count;
813 return retval;
814}
815
816static ssize_t aac_show_reset_adapter(struct class_device *class_dev,
817 char *buf)
818{
819 struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
820 int len, tmp;
821
822 tmp = aac_adapter_check_health(dev);
823 if ((tmp == 0) && dev->in_reset)
824 tmp = -EBUSY;
825 len = snprintf(buf, PAGE_SIZE, "0x%x", tmp);
826 return len;
827}
758 828
759static struct class_device_attribute aac_model = { 829static struct class_device_attribute aac_model = {
760 .attr = { 830 .attr = {
@@ -812,6 +882,14 @@ static struct class_device_attribute aac_max_id = {
812 }, 882 },
813 .show = aac_show_max_id, 883 .show = aac_show_max_id,
814}; 884};
885static struct class_device_attribute aac_reset = {
886 .attr = {
887 .name = "reset_host",
888 .mode = S_IWUSR|S_IRUGO,
889 },
890 .store = aac_store_reset_adapter,
891 .show = aac_show_reset_adapter,
892};
815 893
816static struct class_device_attribute *aac_attrs[] = { 894static struct class_device_attribute *aac_attrs[] = {
817 &aac_model, 895 &aac_model,
@@ -822,6 +900,7 @@ static struct class_device_attribute *aac_attrs[] = {
822 &aac_serial_number, 900 &aac_serial_number,
823 &aac_max_channel, 901 &aac_max_channel,
824 &aac_max_id, 902 &aac_max_id,
903 &aac_reset,
825 NULL 904 NULL
826}; 905};
827 906
@@ -848,6 +927,7 @@ static struct scsi_host_template aac_driver_template = {
848 .bios_param = aac_biosparm, 927 .bios_param = aac_biosparm,
849 .shost_attrs = aac_attrs, 928 .shost_attrs = aac_attrs,
850 .slave_configure = aac_slave_configure, 929 .slave_configure = aac_slave_configure,
930 .change_queue_depth = aac_change_queue_depth,
851 .eh_abort_handler = aac_eh_abort, 931 .eh_abort_handler = aac_eh_abort,
852 .eh_host_reset_handler = aac_eh_reset, 932 .eh_host_reset_handler = aac_eh_reset,
853 .can_queue = AAC_NUM_IO_FIB, 933 .can_queue = AAC_NUM_IO_FIB,
@@ -1086,7 +1166,7 @@ static int __init aac_init(void)
1086{ 1166{
1087 int error; 1167 int error;
1088 1168
1089 printk(KERN_INFO "Adaptec %s driver (%s)\n", 1169 printk(KERN_INFO "Adaptec %s driver %s\n",
1090 AAC_DRIVERNAME, aac_driver_version); 1170 AAC_DRIVERNAME, aac_driver_version);
1091 1171
1092 error = pci_register_driver(&aac_pci_driver); 1172 error = pci_register_driver(&aac_pci_driver);