37 #include <linux/kernel.h>
38 #include <linux/module.h>
40 #include <linux/pci.h>
42 #include <linux/slab.h>
49 #include <scsi/scsi.h>
59 #define AAC_DRIVER_VERSION "1.2-0"
60 #ifndef AAC_DRIVER_BRANCH
61 #define AAC_DRIVER_BRANCH ""
63 #define AAC_DRIVERNAME "aacraid"
65 #ifdef AAC_DRIVER_BUILD
67 #define str(x) _str(x)
68 #define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
70 #define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION AAC_DRIVER_BRANCH
75 "Adaptec Advanced Raid Products, "
76 "HP NetRAID-4M, IBM ServeRAID & ICP SCSI driver");
82 static int aac_cfg_major = -1;
91 #ifdef DECLARE_PCI_DEVICE_TABLE
92 static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
93 #elif defined(__devinitconst)
94 static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
96 static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
98 { 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 },
99 { 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 },
100 { 0x1028, 0x0003, 0x1028, 0x0003, 0, 0, 2 },
101 { 0x1028, 0x0004, 0x1028, 0x00d0, 0, 0, 3 },
102 { 0x1028, 0x0002, 0x1028, 0x00d1, 0, 0, 4 },
103 { 0x1028, 0x0002, 0x1028, 0x00d9, 0, 0, 5 },
104 { 0x1028, 0x000a, 0x1028, 0x0106, 0, 0, 6 },
105 { 0x1028, 0x000a, 0x1028, 0x011b, 0, 0, 7 },
106 { 0x1028, 0x000a, 0x1028, 0x0121, 0, 0, 8 },
107 { 0x9005, 0x0283, 0x9005, 0x0283, 0, 0, 9 },
108 { 0x9005, 0x0284, 0x9005, 0x0284, 0, 0, 10 },
109 { 0x9005, 0x0285, 0x9005, 0x0286, 0, 0, 11 },
110 { 0x9005, 0x0285, 0x9005, 0x0285, 0, 0, 12 },
111 { 0x9005, 0x0285, 0x9005, 0x0287, 0, 0, 13 },
112 { 0x9005, 0x0285, 0x17aa, 0x0286, 0, 0, 14 },
113 { 0x9005, 0x0285, 0x17aa, 0x0287, 0, 0, 15 },
115 { 0x9005, 0x0285, 0x9005, 0x0288, 0, 0, 16 },
116 { 0x9005, 0x0285, 0x9005, 0x0289, 0, 0, 17 },
117 { 0x9005, 0x0285, 0x9005, 0x028a, 0, 0, 18 },
118 { 0x9005, 0x0285, 0x9005, 0x028b, 0, 0, 19 },
119 { 0x9005, 0x0286, 0x9005, 0x028c, 0, 0, 20 },
120 { 0x9005, 0x0286, 0x9005, 0x028d, 0, 0, 21 },
121 { 0x9005, 0x0286, 0x9005, 0x029b, 0, 0, 22 },
122 { 0x9005, 0x0286, 0x9005, 0x029c, 0, 0, 23 },
123 { 0x9005, 0x0286, 0x9005, 0x029d, 0, 0, 24 },
124 { 0x9005, 0x0286, 0x9005, 0x029e, 0, 0, 25 },
125 { 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 },
126 { 0x9005, 0x0286, 0x9005, 0x02a0, 0, 0, 27 },
127 { 0x9005, 0x0286, 0x9005, 0x02a1, 0, 0, 28 },
128 { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 },
129 { 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 },
130 { 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 },
131 { 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 },
132 { 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 33 },
133 { 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 33 },
134 { 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 34 },
135 { 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 35 },
136 { 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 36 },
137 { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 37 },
138 { 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 38 },
139 { 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 39 },
140 { 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 40 },
141 { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 41 },
142 { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 42 },
143 { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 43 },
144 { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 },
145 { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 45 },
146 { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 45 },
147 { 0x9005, 0x0286, 0x1014, 0x9580, 0, 0, 46 },
148 { 0x9005, 0x0286, 0x1014, 0x9540, 0, 0, 47 },
149 { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 },
150 { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 },
151 { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 },
152 { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 },
154 { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 },
155 { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 },
156 { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 54 },
157 { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 55 },
158 { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 56 },
160 { 0x9005, 0x0285, 0x1028,
PCI_ANY_ID, 0, 0, 57 },
161 { 0x9005, 0x0285, 0x17aa,
PCI_ANY_ID, 0, 0, 58 },
196 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"Adaptec 3230S ", 2 },
197 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"Adaptec 3240S ", 2 },
198 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-2020ZCR ", 2 },
199 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-2025ZCR ", 2 },
200 {
aac_rkt_init,
"aacraid",
"ADAPTEC ",
"ASR-2230S PCI-X ", 2 },
201 {
aac_rkt_init,
"aacraid",
"ADAPTEC ",
"ASR-2130S PCI-X ", 1 },
202 {
aac_rkt_init,
"aacraid",
"ADAPTEC ",
"AAR-2820SA ", 1 },
203 {
aac_rkt_init,
"aacraid",
"ADAPTEC ",
"AAR-2620SA ", 1 },
204 {
aac_rkt_init,
"aacraid",
"ADAPTEC ",
"AAR-2420SA ", 1 },
210 {
aac_rx_init,
"aacraid",
"ICP ",
"ICP9085LI ", 1 },
211 {
aac_rx_init,
"aacraid",
"ICP ",
"ICP5085BR ", 1 },
215 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-2020SA ", 1 },
216 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-2025SA ", 1 },
221 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-2026ZCR ", 1 },
222 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"AAR-2610SA ", 1 },
223 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-2240S ", 1 },
224 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-4005 ", 1 },
225 {
aac_rx_init,
"ServeRAID",
"IBM ",
"ServeRAID 8i ", 1 },
226 {
aac_rkt_init,
"ServeRAID",
"IBM ",
"ServeRAID 8k-l8 ", 1 },
227 {
aac_rkt_init,
"ServeRAID",
"IBM ",
"ServeRAID 8k-l4 ", 1 },
228 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-4000 ", 1 },
229 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-4800SAS ", 1 },
230 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"ASR-4805SAS ", 1 },
231 {
aac_rkt_init,
"aacraid",
"ADAPTEC ",
"ASR-3800 ", 1 },
241 {
aac_rx_init,
"aacraid",
"ADAPTEC ",
"RAID ", 2 },
303 return &aac_drivers[devtype];
339 if (capacity >= 2 * 1024 * 1024) {
340 if(capacity >= 4 * 1024 * 1024) {
370 for(num = 0; num < 4; num++) {
371 end_head = entry->end_head;
372 end_sec = entry->end_sector & 0x3f;
378 }
else if(end_head == 127) {
382 }
else if(end_head == 254) {
391 end_head = first->end_head;
392 end_sec = first->end_sector & 0x3f;
396 if (num < 4 && end_sec == param->
sectors) {
398 dprintk((
KERN_DEBUG "Adopting geometry: heads=%d, sectors=%d from partition table %d.\n",
400 }
else if (end_head > 0 || end_sec > 0) {
401 dprintk((
KERN_DEBUG "Strange geometry: heads=%d, sectors=%d in partition table %d.\n",
402 end_head + 1, end_sec, num));
420 static int aac_slave_configure(
struct scsi_device *sdev)
439 unsigned num_lsu = 0;
440 unsigned num_one = 0;
456 (sdev_channel(sdev) != 2)) &&
466 depth = (host->
can_queue - num_one) / num_lsu;
487 static int aac_change_queue_depth(
struct scsi_device *sdev,
int depth,
536 .show = aac_show_raid_level
540 &aac_raid_level_attr,
544 static int aac_ioctl(
struct scsi_device *sdev,
int cmd,
void __user *
arg)
552 static int aac_eh_abort(
struct scsi_cmnd* cmd)
562 host->
host_no, sdev_channel(dev), sdev_id(dev), dev->
lun);
563 switch (cmd->
cmnd[0]) {
607 static int aac_eh_reset(
struct scsi_cmnd* cmd)
642 if ((command != cmd) &&
692 unsigned minor_number = iminor(inode);
697 if (aac->
id == minor_number) {
722 static long aac_cfg_ioctl(
struct file *file,
723 unsigned int cmd,
unsigned long arg)
736 static long aac_compat_do_ioctl(
struct aac_dev *dev,
unsigned cmd,
unsigned long arg)
777 static int aac_compat_ioctl(
struct scsi_device *sdev,
int cmd,
void __user *arg)
780 return aac_compat_do_ioctl(dev, cmd, (
unsigned long)
arg);
783 static long aac_compat_cfg_ioctl(
struct file *file,
unsigned cmd,
unsigned long arg)
787 return aac_compat_do_ioctl(file->
private_data, cmd, arg);
799 while (*cp && *cp !=
' ')
810 static ssize_t aac_show_vendor(
struct device *device,
818 while (*cp && *cp !=
' ')
837 #ifdef AAC_DETAILED_STATUS_INFO
839 "AAC_DETAILED_STATUS_INFO\n");
843 "SAI_READ_CAPACITY_16\n");
849 "SUPPORTED_POWER_MANAGEMENT\n");
855 static ssize_t aac_show_kernel_version(
struct device *device,
864 tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
869 static ssize_t aac_show_monitor_version(
struct device *device,
878 tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
883 static ssize_t aac_show_bios_version(
struct device *device,
892 tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
897 static ssize_t aac_show_serial_number(
struct device *device,
917 static ssize_t aac_show_max_channel(
struct device *device,
924 static ssize_t aac_show_max_id(
struct device *device,
931 static ssize_t aac_store_reset_adapter(
struct device *device,
933 const char *buf,
size_t count)
945 static ssize_t aac_show_reset_adapter(
struct device *device,
964 .show = aac_show_model,
971 .show = aac_show_vendor,
978 .show = aac_show_flags,
982 .name =
"hba_kernel_version",
985 .show = aac_show_kernel_version,
989 .name =
"hba_monitor_version",
992 .show = aac_show_monitor_version,
996 .name =
"hba_bios_version",
999 .show = aac_show_bios_version,
1003 .name =
"serial_number",
1006 .show = aac_show_serial_number,
1010 .name =
"max_channel",
1013 .show = aac_show_max_channel,
1020 .show = aac_show_max_id,
1024 .name =
"reset_host",
1027 .store = aac_store_reset_adapter,
1028 .show = aac_show_reset_adapter,
1035 &aac_kernel_version,
1036 &aac_monitor_version,
1047 return aac_show_serial_number(device, &aac_serial_number, buf);
1052 .unlocked_ioctl = aac_cfg_ioctl,
1053 #ifdef CONFIG_COMPAT
1054 .compat_ioctl = aac_compat_cfg_ioctl,
1056 .open = aac_cfg_open,
1066 #ifdef CONFIG_COMPAT
1067 .compat_ioctl = aac_compat_ioctl,
1069 .queuecommand = aac_queuecommand,
1070 .bios_param = aac_biosparm,
1071 .shost_attrs = aac_attrs,
1072 .slave_configure = aac_slave_configure,
1073 .change_queue_depth = aac_change_queue_depth,
1074 .sdev_attrs = aac_dev_attrs,
1075 .eh_abort_handler = aac_eh_abort,
1076 .eh_host_reset_handler = aac_eh_reset,
1081 #if (AAC_NUM_IO_FIB > 256)
1090 static void __aac_shutdown(
struct aac_dev * aac)
1096 struct fib *fib = &aac->
fibs[
i];
1113 unsigned index =
id->driver_data;
1116 struct list_head *insert = &aac_devices;
1123 if (aac->
id > unique_id)
1125 insert = &aac->
entry;
1146 if (pci_set_dma_mask(pdev, dmamask) ||
1147 pci_set_consistent_dma_mask(pdev, dmamask))
1148 goto out_disable_pdev;
1154 goto out_disable_pdev;
1160 aac = (
struct aac_dev *)shost->hostdata;
1164 aac->
name = aac_driver_template.
name;
1167 INIT_LIST_HEAD(&aac->
entry);
1178 if ((*aac_drivers[index].
init)(aac))
1184 "by driver parameter. This will cause "
1185 "a significant performance decrease!\n",
1190 "by current driver, sync. mode enforced."
1191 "\nPlease update driver to get full performance.\n",
1200 if (IS_ERR(aac->
thread)) {
1202 error = PTR_ERR(aac->
thread);
1212 if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
1245 if (aac_drivers[index].quirks & AAC_QUIRK_34SG)
1262 list_add(&aac->
entry, insert);
1278 pci_set_drvdata(pdev, shost);
1280 error = scsi_add_host(shost, &pdev->
dev);
1288 __aac_shutdown(aac);
1306 static void aac_shutdown(
struct pci_dev *dev)
1308 struct Scsi_Host *shost = pci_get_drvdata(dev);
1310 __aac_shutdown((
struct aac_dev *)shost->hostdata);
1315 struct Scsi_Host *shost = pci_get_drvdata(pdev);
1320 __aac_shutdown(aac);
1334 if (list_empty(&aac_devices)) {
1335 unregister_chrdev(aac_cfg_major,
"aac");
1342 .id_table = aac_pci_tbl,
1343 .probe = aac_probe_one,
1345 .shutdown = aac_shutdown,
1355 error = pci_register_driver(&aac_pci_driver);
1359 aac_cfg_major = register_chrdev( 0,
"aac", &aac_cfg_fops);
1360 if (aac_cfg_major < 0) {
1362 "aacraid: unable to register \"aac\" device.\n");
1368 static void __exit aac_exit(
void)
1370 if (aac_cfg_major > -1)
1371 unregister_chrdev(aac_cfg_major,
"aac");