aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r--drivers/scsi/aacraid/aachba.c327
-rw-r--r--drivers/scsi/aacraid/aacraid.h55
-rw-r--r--drivers/scsi/aacraid/commctrl.c20
-rw-r--r--drivers/scsi/aacraid/comminit.c4
-rw-r--r--drivers/scsi/aacraid/commsup.c20
-rw-r--r--drivers/scsi/aacraid/linit.c106
-rw-r--r--drivers/scsi/aacraid/rkt.c20
-rw-r--r--drivers/scsi/aacraid/rx.c20
-rw-r--r--drivers/scsi/aacraid/sa.c22
9 files changed, 427 insertions, 167 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index ccdf440021fb..a8e3dfcd0dc7 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -133,6 +133,7 @@ struct inquiry_data {
133 133
134static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); 134static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap);
135static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); 135static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg);
136static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg);
136static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); 137static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);
137#ifdef AAC_DETAILED_STATUS_INFO 138#ifdef AAC_DETAILED_STATUS_INFO
138static char *aac_get_status_string(u32 status); 139static char *aac_get_status_string(u32 status);
@@ -348,6 +349,27 @@ static void aac_io_done(struct scsi_cmnd * scsicmd)
348 spin_unlock_irqrestore(host->host_lock, cpu_flags); 349 spin_unlock_irqrestore(host->host_lock, cpu_flags);
349} 350}
350 351
352static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
353{
354 void *buf;
355 unsigned int transfer_len;
356 struct scatterlist *sg = scsicmd->request_buffer;
357
358 if (scsicmd->use_sg) {
359 buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
360 transfer_len = min(sg->length, len + offset);
361 } else {
362 buf = scsicmd->request_buffer;
363 transfer_len = min(scsicmd->request_bufflen, len + offset);
364 }
365
366 memcpy(buf + offset, data, transfer_len - offset);
367
368 if (scsicmd->use_sg)
369 kunmap_atomic(buf - sg->offset, KM_IRQ0);
370
371}
372
351static void get_container_name_callback(void *context, struct fib * fibptr) 373static void get_container_name_callback(void *context, struct fib * fibptr)
352{ 374{
353 struct aac_get_name_resp * get_name_reply; 375 struct aac_get_name_resp * get_name_reply;
@@ -363,18 +385,22 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
363 /* Failure is irrelevant, using default value instead */ 385 /* Failure is irrelevant, using default value instead */
364 if ((le32_to_cpu(get_name_reply->status) == CT_OK) 386 if ((le32_to_cpu(get_name_reply->status) == CT_OK)
365 && (get_name_reply->data[0] != '\0')) { 387 && (get_name_reply->data[0] != '\0')) {
366 int count; 388 char *sp = get_name_reply->data;
367 char * dp;
368 char * sp = get_name_reply->data;
369 sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0'; 389 sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0';
370 while (*sp == ' ') 390 while (*sp == ' ')
371 ++sp; 391 ++sp;
372 count = sizeof(((struct inquiry_data *)NULL)->inqd_pid); 392 if (*sp) {
373 dp = ((struct inquiry_data *)scsicmd->request_buffer)->inqd_pid; 393 char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)];
374 if (*sp) do { 394 int count = sizeof(d);
375 *dp++ = (*sp) ? *sp++ : ' '; 395 char *dp = d;
376 } while (--count > 0); 396 do {
397 *dp++ = (*sp) ? *sp++ : ' ';
398 } while (--count > 0);
399 aac_internal_transfer(scsicmd, d,
400 offsetof(struct inquiry_data, inqd_pid), sizeof(d));
401 }
377 } 402 }
403
378 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 404 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
379 405
380 fib_complete(fibptr); 406 fib_complete(fibptr);
@@ -777,34 +803,36 @@ int aac_get_adapter_info(struct aac_dev* dev)
777 /* 803 /*
778 * 57 scatter gather elements 804 * 57 scatter gather elements
779 */ 805 */
780 dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - 806 if (!(dev->raw_io_interface)) {
781 sizeof(struct aac_fibhdr) - 807 dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
782 sizeof(struct aac_write) + sizeof(struct sgmap)) /
783 sizeof(struct sgmap);
784 if (dev->dac_support) {
785 /*
786 * 38 scatter gather elements
787 */
788 dev->scsi_host_ptr->sg_tablesize =
789 (dev->max_fib_size -
790 sizeof(struct aac_fibhdr) - 808 sizeof(struct aac_fibhdr) -
791 sizeof(struct aac_write64) + 809 sizeof(struct aac_write) + sizeof(struct sgmap)) /
792 sizeof(struct sgmap64)) / 810 sizeof(struct sgmap);
793 sizeof(struct sgmap64); 811 if (dev->dac_support) {
794 } 812 /*
795 dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; 813 * 38 scatter gather elements
796 if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { 814 */
797 /* 815 dev->scsi_host_ptr->sg_tablesize =
798 * Worst case size that could cause sg overflow when 816 (dev->max_fib_size -
799 * we break up SG elements that are larger than 64KB. 817 sizeof(struct aac_fibhdr) -
800 * Would be nice if we could tell the SCSI layer what 818 sizeof(struct aac_write64) +
801 * the maximum SG element size can be. Worst case is 819 sizeof(struct sgmap64)) /
802 * (sg_tablesize-1) 4KB elements with one 64KB 820 sizeof(struct sgmap64);
803 * element. 821 }
804 * 32bit -> 468 or 238KB 64bit -> 424 or 212KB 822 dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
805 */ 823 if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
806 dev->scsi_host_ptr->max_sectors = 824 /*
807 (dev->scsi_host_ptr->sg_tablesize * 8) + 112; 825 * Worst case size that could cause sg overflow when
826 * we break up SG elements that are larger than 64KB.
827 * Would be nice if we could tell the SCSI layer what
828 * the maximum SG element size can be. Worst case is
829 * (sg_tablesize-1) 4KB elements with one 64KB
830 * element.
831 * 32bit -> 468 or 238KB 64bit -> 424 or 212KB
832 */
833 dev->scsi_host_ptr->max_sectors =
834 (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
835 }
808 } 836 }
809 837
810 fib_complete(fibptr); 838 fib_complete(fibptr);
@@ -814,12 +842,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
814} 842}
815 843
816 844
817static void read_callback(void *context, struct fib * fibptr) 845static void io_callback(void *context, struct fib * fibptr)
818{ 846{
819 struct aac_dev *dev; 847 struct aac_dev *dev;
820 struct aac_read_reply *readreply; 848 struct aac_read_reply *readreply;
821 struct scsi_cmnd *scsicmd; 849 struct scsi_cmnd *scsicmd;
822 u32 lba;
823 u32 cid; 850 u32 cid;
824 851
825 scsicmd = (struct scsi_cmnd *) context; 852 scsicmd = (struct scsi_cmnd *) context;
@@ -827,8 +854,7 @@ static void read_callback(void *context, struct fib * fibptr)
827 dev = (struct aac_dev *)scsicmd->device->host->hostdata; 854 dev = (struct aac_dev *)scsicmd->device->host->hostdata;
828 cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); 855 cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
829 856
830 lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; 857 dprintk((KERN_DEBUG "io_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3], jiffies));
831 dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
832 858
833 if (fibptr == NULL) 859 if (fibptr == NULL)
834 BUG(); 860 BUG();
@@ -847,7 +873,7 @@ static void read_callback(void *context, struct fib * fibptr)
847 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 873 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
848 else { 874 else {
849#ifdef AAC_DETAILED_STATUS_INFO 875#ifdef AAC_DETAILED_STATUS_INFO
850 printk(KERN_WARNING "read_callback: io failed, status = %d\n", 876 printk(KERN_WARNING "io_callback: io failed, status = %d\n",
851 le32_to_cpu(readreply->status)); 877 le32_to_cpu(readreply->status));
852#endif 878#endif
853 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; 879 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
@@ -867,53 +893,6 @@ static void read_callback(void *context, struct fib * fibptr)
867 aac_io_done(scsicmd); 893 aac_io_done(scsicmd);
868} 894}
869 895
870static void write_callback(void *context, struct fib * fibptr)
871{
872 struct aac_dev *dev;
873 struct aac_write_reply *writereply;
874 struct scsi_cmnd *scsicmd;
875 u32 lba;
876 u32 cid;
877
878 scsicmd = (struct scsi_cmnd *) context;
879 dev = (struct aac_dev *)scsicmd->device->host->hostdata;
880 cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
881
882 lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
883 dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
884 if (fibptr == NULL)
885 BUG();
886
887 if(scsicmd->use_sg)
888 pci_unmap_sg(dev->pdev,
889 (struct scatterlist *)scsicmd->buffer,
890 scsicmd->use_sg,
891 scsicmd->sc_data_direction);
892 else if(scsicmd->request_bufflen)
893 pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle,
894 scsicmd->request_bufflen,
895 scsicmd->sc_data_direction);
896
897 writereply = (struct aac_write_reply *) fib_data(fibptr);
898 if (le32_to_cpu(writereply->status) == ST_OK)
899 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
900 else {
901 printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status);
902 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
903 set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
904 HARDWARE_ERROR,
905 SENCODE_INTERNAL_TARGET_FAILURE,
906 ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
907 0, 0);
908 memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
909 sizeof(struct sense_data));
910 }
911
912 fib_complete(fibptr);
913 fib_free(fibptr);
914 aac_io_done(scsicmd);
915}
916
917static int aac_read(struct scsi_cmnd * scsicmd, int cid) 896static int aac_read(struct scsi_cmnd * scsicmd, int cid)
918{ 897{
919 u32 lba; 898 u32 lba;
@@ -954,7 +933,32 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
954 933
955 fib_init(cmd_fibcontext); 934 fib_init(cmd_fibcontext);
956 935
957 if (dev->dac_support == 1) { 936 if (dev->raw_io_interface) {
937 struct aac_raw_io *readcmd;
938 readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
939 readcmd->block[0] = cpu_to_le32(lba);
940 readcmd->block[1] = 0;
941 readcmd->count = cpu_to_le32(count<<9);
942 readcmd->cid = cpu_to_le16(cid);
943 readcmd->flags = cpu_to_le16(1);
944 readcmd->bpTotal = 0;
945 readcmd->bpComplete = 0;
946
947 aac_build_sgraw(scsicmd, &readcmd->sg);
948 fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
949 if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))
950 BUG();
951 /*
952 * Now send the Fib to the adapter
953 */
954 status = fib_send(ContainerRawIo,
955 cmd_fibcontext,
956 fibsize,
957 FsaNormal,
958 0, 1,
959 (fib_callback) io_callback,
960 (void *) scsicmd);
961 } else if (dev->dac_support == 1) {
958 struct aac_read64 *readcmd; 962 struct aac_read64 *readcmd;
959 readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); 963 readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
960 readcmd->command = cpu_to_le32(VM_CtHostRead64); 964 readcmd->command = cpu_to_le32(VM_CtHostRead64);
@@ -968,7 +972,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
968 fibsize = sizeof(struct aac_read64) + 972 fibsize = sizeof(struct aac_read64) +
969 ((le32_to_cpu(readcmd->sg.count) - 1) * 973 ((le32_to_cpu(readcmd->sg.count) - 1) *
970 sizeof (struct sgentry64)); 974 sizeof (struct sgentry64));
971 BUG_ON (fibsize > (sizeof(struct hw_fib) - 975 BUG_ON (fibsize > (dev->max_fib_size -
972 sizeof(struct aac_fibhdr))); 976 sizeof(struct aac_fibhdr)));
973 /* 977 /*
974 * Now send the Fib to the adapter 978 * Now send the Fib to the adapter
@@ -978,7 +982,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
978 fibsize, 982 fibsize,
979 FsaNormal, 983 FsaNormal,
980 0, 1, 984 0, 1,
981 (fib_callback) read_callback, 985 (fib_callback) io_callback,
982 (void *) scsicmd); 986 (void *) scsicmd);
983 } else { 987 } else {
984 struct aac_read *readcmd; 988 struct aac_read *readcmd;
@@ -1002,7 +1006,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
1002 fibsize, 1006 fibsize,
1003 FsaNormal, 1007 FsaNormal,
1004 0, 1, 1008 0, 1,
1005 (fib_callback) read_callback, 1009 (fib_callback) io_callback,
1006 (void *) scsicmd); 1010 (void *) scsicmd);
1007 } 1011 }
1008 1012
@@ -1061,7 +1065,32 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
1061 } 1065 }
1062 fib_init(cmd_fibcontext); 1066 fib_init(cmd_fibcontext);
1063 1067
1064 if(dev->dac_support == 1) { 1068 if (dev->raw_io_interface) {
1069 struct aac_raw_io *writecmd;
1070 writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
1071 writecmd->block[0] = cpu_to_le32(lba);
1072 writecmd->block[1] = 0;
1073 writecmd->count = cpu_to_le32(count<<9);
1074 writecmd->cid = cpu_to_le16(cid);
1075 writecmd->flags = 0;
1076 writecmd->bpTotal = 0;
1077 writecmd->bpComplete = 0;
1078
1079 aac_build_sgraw(scsicmd, &writecmd->sg);
1080 fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw));
1081 if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))
1082 BUG();
1083 /*
1084 * Now send the Fib to the adapter
1085 */
1086 status = fib_send(ContainerRawIo,
1087 cmd_fibcontext,
1088 fibsize,
1089 FsaNormal,
1090 0, 1,
1091 (fib_callback) io_callback,
1092 (void *) scsicmd);
1093 } else if (dev->dac_support == 1) {
1065 struct aac_write64 *writecmd; 1094 struct aac_write64 *writecmd;
1066 writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); 1095 writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext);
1067 writecmd->command = cpu_to_le32(VM_CtHostWrite64); 1096 writecmd->command = cpu_to_le32(VM_CtHostWrite64);
@@ -1085,7 +1114,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
1085 fibsize, 1114 fibsize,
1086 FsaNormal, 1115 FsaNormal,
1087 0, 1, 1116 0, 1,
1088 (fib_callback) write_callback, 1117 (fib_callback) io_callback,
1089 (void *) scsicmd); 1118 (void *) scsicmd);
1090 } else { 1119 } else {
1091 struct aac_write *writecmd; 1120 struct aac_write *writecmd;
@@ -1111,7 +1140,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
1111 fibsize, 1140 fibsize,
1112 FsaNormal, 1141 FsaNormal,
1113 0, 1, 1142 0, 1,
1114 (fib_callback) write_callback, 1143 (fib_callback) io_callback,
1115 (void *) scsicmd); 1144 (void *) scsicmd);
1116 } 1145 }
1117 1146
@@ -1340,44 +1369,45 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1340 switch (scsicmd->cmnd[0]) { 1369 switch (scsicmd->cmnd[0]) {
1341 case INQUIRY: 1370 case INQUIRY:
1342 { 1371 {
1343 struct inquiry_data *inq_data_ptr; 1372 struct inquiry_data inq_data;
1344 1373
1345 dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id)); 1374 dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id));
1346 inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer; 1375 memset(&inq_data, 0, sizeof (struct inquiry_data));
1347 memset(inq_data_ptr, 0, sizeof (struct inquiry_data));
1348 1376
1349 inq_data_ptr->inqd_ver = 2; /* claim compliance to SCSI-2 */ 1377 inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */
1350 inq_data_ptr->inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ 1378 inq_data.inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */
1351 inq_data_ptr->inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ 1379 inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
1352 inq_data_ptr->inqd_len = 31; 1380 inq_data.inqd_len = 31;
1353 /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ 1381 /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
1354 inq_data_ptr->inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */ 1382 inq_data.inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */
1355 /* 1383 /*
1356 * Set the Vendor, Product, and Revision Level 1384 * Set the Vendor, Product, and Revision Level
1357 * see: <vendor>.c i.e. aac.c 1385 * see: <vendor>.c i.e. aac.c
1358 */ 1386 */
1359 if (scsicmd->device->id == host->this_id) { 1387 if (scsicmd->device->id == host->this_id) {
1360 setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), (sizeof(container_types)/sizeof(char *))); 1388 setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
1361 inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */ 1389 inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
1390 aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
1362 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 1391 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
1363 scsicmd->scsi_done(scsicmd); 1392 scsicmd->scsi_done(scsicmd);
1364 return 0; 1393 return 0;
1365 } 1394 }
1366 setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr[cid].type); 1395 setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
1367 inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ 1396 inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
1397 aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
1368 return aac_get_container_name(scsicmd, cid); 1398 return aac_get_container_name(scsicmd, cid);
1369 } 1399 }
1370 case READ_CAPACITY: 1400 case READ_CAPACITY:
1371 { 1401 {
1372 u32 capacity; 1402 u32 capacity;
1373 char *cp; 1403 char cp[8];
1374 1404
1375 dprintk((KERN_DEBUG "READ CAPACITY command.\n")); 1405 dprintk((KERN_DEBUG "READ CAPACITY command.\n"));
1376 if (fsa_dev_ptr[cid].size <= 0x100000000LL) 1406 if (fsa_dev_ptr[cid].size <= 0x100000000LL)
1377 capacity = fsa_dev_ptr[cid].size - 1; 1407 capacity = fsa_dev_ptr[cid].size - 1;
1378 else 1408 else
1379 capacity = (u32)-1; 1409 capacity = (u32)-1;
1380 cp = scsicmd->request_buffer; 1410
1381 cp[0] = (capacity >> 24) & 0xff; 1411 cp[0] = (capacity >> 24) & 0xff;
1382 cp[1] = (capacity >> 16) & 0xff; 1412 cp[1] = (capacity >> 16) & 0xff;
1383 cp[2] = (capacity >> 8) & 0xff; 1413 cp[2] = (capacity >> 8) & 0xff;
@@ -1386,6 +1416,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1386 cp[5] = 0; 1416 cp[5] = 0;
1387 cp[6] = 2; 1417 cp[6] = 2;
1388 cp[7] = 0; 1418 cp[7] = 0;
1419 aac_internal_transfer(scsicmd, cp, 0, sizeof(cp));
1389 1420
1390 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 1421 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
1391 scsicmd->scsi_done(scsicmd); 1422 scsicmd->scsi_done(scsicmd);
@@ -1395,15 +1426,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1395 1426
1396 case MODE_SENSE: 1427 case MODE_SENSE:
1397 { 1428 {
1398 char *mode_buf; 1429 char mode_buf[4];
1399 1430
1400 dprintk((KERN_DEBUG "MODE SENSE command.\n")); 1431 dprintk((KERN_DEBUG "MODE SENSE command.\n"));
1401 mode_buf = scsicmd->request_buffer;
1402 mode_buf[0] = 3; /* Mode data length */ 1432 mode_buf[0] = 3; /* Mode data length */
1403 mode_buf[1] = 0; /* Medium type - default */ 1433 mode_buf[1] = 0; /* Medium type - default */
1404 mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */ 1434 mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */
1405 mode_buf[3] = 0; /* Block descriptor length */ 1435 mode_buf[3] = 0; /* Block descriptor length */
1406 1436
1437 aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
1407 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 1438 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
1408 scsicmd->scsi_done(scsicmd); 1439 scsicmd->scsi_done(scsicmd);
1409 1440
@@ -1411,10 +1442,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1411 } 1442 }
1412 case MODE_SENSE_10: 1443 case MODE_SENSE_10:
1413 { 1444 {
1414 char *mode_buf; 1445 char mode_buf[8];
1415 1446
1416 dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n")); 1447 dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
1417 mode_buf = scsicmd->request_buffer;
1418 mode_buf[0] = 0; /* Mode data length (MSB) */ 1448 mode_buf[0] = 0; /* Mode data length (MSB) */
1419 mode_buf[1] = 6; /* Mode data length (LSB) */ 1449 mode_buf[1] = 6; /* Mode data length (LSB) */
1420 mode_buf[2] = 0; /* Medium type - default */ 1450 mode_buf[2] = 0; /* Medium type - default */
@@ -1423,6 +1453,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1423 mode_buf[5] = 0; /* reserved */ 1453 mode_buf[5] = 0; /* reserved */
1424 mode_buf[6] = 0; /* Block descriptor length (MSB) */ 1454 mode_buf[6] = 0; /* Block descriptor length (MSB) */
1425 mode_buf[7] = 0; /* Block descriptor length (LSB) */ 1455 mode_buf[7] = 0; /* Block descriptor length (LSB) */
1456 aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
1426 1457
1427 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; 1458 scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
1428 scsicmd->scsi_done(scsicmd); 1459 scsicmd->scsi_done(scsicmd);
@@ -1894,7 +1925,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
1894 srbcmd->id = cpu_to_le32(scsicmd->device->id); 1925 srbcmd->id = cpu_to_le32(scsicmd->device->id);
1895 srbcmd->lun = cpu_to_le32(scsicmd->device->lun); 1926 srbcmd->lun = cpu_to_le32(scsicmd->device->lun);
1896 srbcmd->flags = cpu_to_le32(flag); 1927 srbcmd->flags = cpu_to_le32(flag);
1897 timeout = (scsicmd->timeout-jiffies)/HZ; 1928 timeout = scsicmd->timeout_per_command/HZ;
1898 if(timeout == 0){ 1929 if(timeout == 0){
1899 timeout = 1; 1930 timeout = 1;
1900 } 1931 }
@@ -2077,6 +2108,76 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
2077 return byte_count; 2108 return byte_count;
2078} 2109}
2079 2110
2111static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg)
2112{
2113 struct Scsi_Host *host = scsicmd->device->host;
2114 struct aac_dev *dev = (struct aac_dev *)host->hostdata;
2115 unsigned long byte_count = 0;
2116
2117 // Get rid of old data
2118 psg->count = 0;
2119 psg->sg[0].next = 0;
2120 psg->sg[0].prev = 0;
2121 psg->sg[0].addr[0] = 0;
2122 psg->sg[0].addr[1] = 0;
2123 psg->sg[0].count = 0;
2124 psg->sg[0].flags = 0;
2125 if (scsicmd->use_sg) {
2126 struct scatterlist *sg;
2127 int i;
2128 int sg_count;
2129 sg = (struct scatterlist *) scsicmd->request_buffer;
2130
2131 sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
2132 scsicmd->sc_data_direction);
2133
2134 for (i = 0; i < sg_count; i++) {
2135 int count = sg_dma_len(sg);
2136 u64 addr = sg_dma_address(sg);
2137 psg->sg[i].next = 0;
2138 psg->sg[i].prev = 0;
2139 psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32));
2140 psg->sg[i].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
2141 psg->sg[i].count = cpu_to_le32(count);
2142 psg->sg[i].flags = 0;
2143 byte_count += count;
2144 sg++;
2145 }
2146 psg->count = cpu_to_le32(sg_count);
2147 /* hba wants the size to be exact */
2148 if(byte_count > scsicmd->request_bufflen){
2149 u32 temp = le32_to_cpu(psg->sg[i-1].count) -
2150 (byte_count - scsicmd->request_bufflen);
2151 psg->sg[i-1].count = cpu_to_le32(temp);
2152 byte_count = scsicmd->request_bufflen;
2153 }
2154 /* Check for command underflow */
2155 if(scsicmd->underflow && (byte_count < scsicmd->underflow)){
2156 printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",
2157 byte_count, scsicmd->underflow);
2158 }
2159 }
2160 else if(scsicmd->request_bufflen) {
2161 int count;
2162 u64 addr;
2163 scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
2164 scsicmd->request_buffer,
2165 scsicmd->request_bufflen,
2166 scsicmd->sc_data_direction);
2167 addr = scsicmd->SCp.dma_handle;
2168 count = scsicmd->request_bufflen;
2169 psg->count = cpu_to_le32(1);
2170 psg->sg[0].next = 0;
2171 psg->sg[0].prev = 0;
2172 psg->sg[0].addr[1] = cpu_to_le32((u32)(addr>>32));
2173 psg->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
2174 psg->sg[0].count = cpu_to_le32(count);
2175 psg->sg[0].flags = 0;
2176 byte_count = scsicmd->request_bufflen;
2177 }
2178 return byte_count;
2179}
2180
2080#ifdef AAC_DETAILED_STATUS_INFO 2181#ifdef AAC_DETAILED_STATUS_INFO
2081 2182
2082struct aac_srb_status_info { 2183struct aac_srb_status_info {
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 4ab07861b457..e40528185d48 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -110,6 +110,22 @@ struct user_sgentry64 {
110 u32 count; /* Length. */ 110 u32 count; /* Length. */
111}; 111};
112 112
113struct sgentryraw {
114 __le32 next; /* reserved for F/W use */
115 __le32 prev; /* reserved for F/W use */
116 __le32 addr[2];
117 __le32 count;
118 __le32 flags; /* reserved for F/W use */
119};
120
121struct user_sgentryraw {
122 u32 next; /* reserved for F/W use */
123 u32 prev; /* reserved for F/W use */
124 u32 addr[2];
125 u32 count;
126 u32 flags; /* reserved for F/W use */
127};
128
113/* 129/*
114 * SGMAP 130 * SGMAP
115 * 131 *
@@ -137,6 +153,16 @@ struct user_sgmap64 {
137 struct user_sgentry64 sg[1]; 153 struct user_sgentry64 sg[1];
138}; 154};
139 155
156struct sgmapraw {
157 __le32 count;
158 struct sgentryraw sg[1];
159};
160
161struct user_sgmapraw {
162 u32 count;
163 struct user_sgentryraw sg[1];
164};
165
140struct creation_info 166struct creation_info
141{ 167{
142 u8 buildnum; /* e.g., 588 */ 168 u8 buildnum; /* e.g., 588 */
@@ -351,6 +377,7 @@ struct hw_fib {
351 */ 377 */
352#define ContainerCommand 500 378#define ContainerCommand 500
353#define ContainerCommand64 501 379#define ContainerCommand64 501
380#define ContainerRawIo 502
354/* 381/*
355 * Cluster Commands 382 * Cluster Commands
356 */ 383 */
@@ -456,6 +483,7 @@ struct adapter_ops
456{ 483{
457 void (*adapter_interrupt)(struct aac_dev *dev); 484 void (*adapter_interrupt)(struct aac_dev *dev);
458 void (*adapter_notify)(struct aac_dev *dev, u32 event); 485 void (*adapter_notify)(struct aac_dev *dev, u32 event);
486 void (*adapter_disable_int)(struct aac_dev *dev);
459 int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); 487 int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
460 int (*adapter_check_health)(struct aac_dev *dev); 488 int (*adapter_check_health)(struct aac_dev *dev);
461}; 489};
@@ -981,6 +1009,9 @@ struct aac_dev
981 u8 nondasd_support; 1009 u8 nondasd_support;
982 u8 dac_support; 1010 u8 dac_support;
983 u8 raid_scsi_mode; 1011 u8 raid_scsi_mode;
1012 /* macro side-effects BEWARE */
1013# define raw_io_interface \
1014 init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
984 u8 printf_enabled; 1015 u8 printf_enabled;
985}; 1016};
986 1017
@@ -990,6 +1021,9 @@ struct aac_dev
990#define aac_adapter_notify(dev, event) \ 1021#define aac_adapter_notify(dev, event) \
991 (dev)->a_ops.adapter_notify(dev, event) 1022 (dev)->a_ops.adapter_notify(dev, event)
992 1023
1024#define aac_adapter_disable_int(dev) \
1025 (dev)->a_ops.adapter_disable_int(dev)
1026
993#define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \ 1027#define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
994 (dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) 1028 (dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)
995 1029
@@ -1156,6 +1190,17 @@ struct aac_write_reply
1156 __le32 committed; 1190 __le32 committed;
1157}; 1191};
1158 1192
1193struct aac_raw_io
1194{
1195 __le32 block[2];
1196 __le32 count;
1197 __le16 cid;
1198 __le16 flags; /* 00 W, 01 R */
1199 __le16 bpTotal; /* reserved for F/W use */
1200 __le16 bpComplete; /* reserved for F/W use */
1201 struct sgmapraw sg;
1202};
1203
1159#define CT_FLUSH_CACHE 129 1204#define CT_FLUSH_CACHE 129
1160struct aac_synchronize { 1205struct aac_synchronize {
1161 __le32 command; /* VM_ContainerConfig */ 1206 __le32 command; /* VM_ContainerConfig */
@@ -1196,7 +1241,7 @@ struct aac_srb
1196}; 1241};
1197 1242
1198/* 1243/*
1199 * This and assocated data structs are used by the 1244 * This and associated data structs are used by the
1200 * ioctl caller and are in cpu order. 1245 * ioctl caller and are in cpu order.
1201 */ 1246 */
1202struct user_aac_srb 1247struct user_aac_srb
@@ -1508,11 +1553,12 @@ struct fib_ioctl
1508 1553
1509struct revision 1554struct revision
1510{ 1555{
1511 u32 compat; 1556 __le32 compat;
1512 u32 version; 1557 __le32 version;
1513 u32 build; 1558 __le32 build;
1514}; 1559};
1515 1560
1561
1516/* 1562/*
1517 * Ugly - non Linux like ioctl coding for back compat. 1563 * Ugly - non Linux like ioctl coding for back compat.
1518 */ 1564 */
@@ -1733,3 +1779,4 @@ int aac_get_adapter_info(struct aac_dev* dev);
1733int aac_send_shutdown(struct aac_dev *dev); 1779int aac_send_shutdown(struct aac_dev *dev);
1734extern int numacb; 1780extern int numacb;
1735extern int acbsize; 1781extern int acbsize;
1782extern char aac_driver_version[];
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 85387099aab2..71f1cad9b5f0 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -287,7 +287,6 @@ return_fib:
287 kfree(fib->hw_fib); 287 kfree(fib->hw_fib);
288 kfree(fib); 288 kfree(fib);
289 status = 0; 289 status = 0;
290 fibctx->jiffies = jiffies/HZ;
291 } else { 290 } else {
292 spin_unlock_irqrestore(&dev->fib_lock, flags); 291 spin_unlock_irqrestore(&dev->fib_lock, flags);
293 if (f.wait) { 292 if (f.wait) {
@@ -302,6 +301,7 @@ return_fib:
302 status = -EAGAIN; 301 status = -EAGAIN;
303 } 302 }
304 } 303 }
304 fibctx->jiffies = jiffies/HZ;
305 return status; 305 return status;
306} 306}
307 307
@@ -405,10 +405,20 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
405static int check_revision(struct aac_dev *dev, void __user *arg) 405static int check_revision(struct aac_dev *dev, void __user *arg)
406{ 406{
407 struct revision response; 407 struct revision response;
408 408 char *driver_version = aac_driver_version;
409 response.compat = 1; 409 u32 version;
410 response.version = le32_to_cpu(dev->adapter_info.kernelrev); 410
411 response.build = le32_to_cpu(dev->adapter_info.kernelbuild); 411 response.compat = cpu_to_le32(1);
412 version = (simple_strtol(driver_version,
413 &driver_version, 10) << 24) | 0x00000400;
414 version += simple_strtol(driver_version + 1, &driver_version, 10) << 16;
415 version += simple_strtol(driver_version + 1, NULL, 10);
416 response.version = cpu_to_le32(version);
417# if (defined(AAC_DRIVER_BUILD))
418 response.build = cpu_to_le32(AAC_DRIVER_BUILD);
419# else
420 response.build = cpu_to_le32(9999);
421# endif
412 422
413 if (copy_to_user(arg, &response, sizeof(response))) 423 if (copy_to_user(arg, &response, sizeof(response)))
414 return -EFAULT; 424 return -EFAULT;
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 43557bf661f6..75abd0453289 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -44,7 +44,9 @@
44 44
45#include "aacraid.h" 45#include "aacraid.h"
46 46
47struct aac_common aac_config; 47struct aac_common aac_config = {
48 .irq_mod = 1
49};
48 50
49static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign) 51static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
50{ 52{
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 5322865942e2..a1d303f03480 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -254,6 +254,7 @@ static void fib_dealloc(struct fib * fibptr)
254static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify) 254static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify)
255{ 255{
256 struct aac_queue * q; 256 struct aac_queue * q;
257 unsigned long idx;
257 258
258 /* 259 /*
259 * All of the queues wrap when they reach the end, so we check 260 * All of the queues wrap when they reach the end, so we check
@@ -263,10 +264,23 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
263 */ 264 */
264 265
265 q = &dev->queues->queue[qid]; 266 q = &dev->queues->queue[qid];
266 267
267 *index = le32_to_cpu(*(q->headers.producer)); 268 idx = *index = le32_to_cpu(*(q->headers.producer));
268 if ((*index - 2) == le32_to_cpu(*(q->headers.consumer))) 269 /* Interrupt Moderation, only interrupt for first two entries */
270 if (idx != le32_to_cpu(*(q->headers.consumer))) {
271 if (--idx == 0) {
272 if (qid == AdapHighCmdQueue)
273 idx = ADAP_HIGH_CMD_ENTRIES;
274 else if (qid == AdapNormCmdQueue)
275 idx = ADAP_NORM_CMD_ENTRIES;
276 else if (qid == AdapHighRespQueue)
277 idx = ADAP_HIGH_RESP_ENTRIES;
278 else if (qid == AdapNormRespQueue)
279 idx = ADAP_NORM_RESP_ENTRIES;
280 }
281 if (idx != le32_to_cpu(*(q->headers.consumer)))
269 *nonotify = 1; 282 *nonotify = 1;
283 }
270 284
271 if (qid == AdapHighCmdQueue) { 285 if (qid == AdapHighCmdQueue) {
272 if (*index >= ADAP_HIGH_CMD_ENTRIES) 286 if (*index >= ADAP_HIGH_CMD_ENTRIES)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 562da90480a1..4ff29d7f5825 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -27,8 +27,11 @@
27 * Abstract: Linux Driver entry module for Adaptec RAID Array Controller 27 * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
28 */ 28 */
29 29
30#define AAC_DRIVER_VERSION "1.1.2-lk2" 30#define AAC_DRIVER_VERSION "1.1-4"
31#define AAC_DRIVER_BUILD_DATE __DATE__ 31#ifndef AAC_DRIVER_BRANCH
32#define AAC_DRIVER_BRANCH ""
33#endif
34#define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__
32#define AAC_DRIVERNAME "aacraid" 35#define AAC_DRIVERNAME "aacraid"
33 36
34#include <linux/compat.h> 37#include <linux/compat.h>
@@ -58,16 +61,24 @@
58 61
59#include "aacraid.h" 62#include "aacraid.h"
60 63
64#ifdef AAC_DRIVER_BUILD
65#define _str(x) #x
66#define str(x) _str(x)
67#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
68#else
69#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION AAC_DRIVER_BRANCH " " AAC_DRIVER_BUILD_DATE
70#endif
61 71
62MODULE_AUTHOR("Red Hat Inc and Adaptec"); 72MODULE_AUTHOR("Red Hat Inc and Adaptec");
63MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, " 73MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, "
64 "Adaptec Advanced Raid Products, " 74 "Adaptec Advanced Raid Products, "
65 "and HP NetRAID-4M SCSI driver"); 75 "and HP NetRAID-4M SCSI driver");
66MODULE_LICENSE("GPL"); 76MODULE_LICENSE("GPL");
67MODULE_VERSION(AAC_DRIVER_VERSION); 77MODULE_VERSION(AAC_DRIVER_FULL_VERSION);
68 78
69static LIST_HEAD(aac_devices); 79static LIST_HEAD(aac_devices);
70static int aac_cfg_major = -1; 80static int aac_cfg_major = -1;
81char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
71 82
72/* 83/*
73 * Because of the way Linux names scsi devices, the order in this table has 84 * Because of the way Linux names scsi devices, the order in this table has
@@ -109,36 +120,39 @@ static struct pci_device_id aac_pci_tbl[] = {
109 { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */ 120 { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */
110 { 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */ 121 { 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */
111 { 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */ 122 { 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */
112 { 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 32 }, /* Themisto Jupiter Platform */ 123 { 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 }, /* ICP9067MA (Intruder-6) */
113 { 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 32 }, /* Themisto Jupiter Platform */ 124 { 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 33 }, /* Themisto Jupiter Platform */
114 { 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 33 }, /* Callisto Jupiter Platform */ 125 { 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 33 }, /* Themisto Jupiter Platform */
115 { 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 34 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */ 126 { 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 34 }, /* Callisto Jupiter Platform */
116 { 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 35 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */ 127 { 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 35 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
117 { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 36 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */ 128 { 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 36 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
118 { 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 37 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */ 129 { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 37 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
119 { 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 38 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */ 130 { 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 38 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
120 { 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 39 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */ 131 { 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 39 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
121 { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 40 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ 132 { 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 40 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
122 { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 41 }, /* AAR-2610SA PCI SATA 6ch */ 133 { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 41 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
123 { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 42 }, /* ASR-2240S (SabreExpress) */ 134 { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 42 }, /* AAR-2610SA PCI SATA 6ch */
124 { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 43 }, /* ASR-4005SAS */ 135 { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 43 }, /* ASR-2240S (SabreExpress) */
125 { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 44 }, /* IBM 8i (AvonPark) */ 136 { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005SAS */
126 { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 44 }, /* IBM 8i (AvonPark Lite) */ 137 { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 45 }, /* IBM 8i (AvonPark) */
127 { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 45 }, /* ASR-4000SAS (BlackBird) */ 138 { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 45 }, /* IBM 8i (AvonPark Lite) */
128 { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 46 }, /* ASR-4800SAS (Marauder-X) */ 139 { 0x9005, 0x0286, 0x1014, 0x9580, 0, 0, 46 }, /* IBM 8k/8k-l8 (Aurora) */
129 { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 47 }, /* ASR-4805SAS (Marauder-E) */ 140 { 0x9005, 0x0286, 0x1014, 0x9540, 0, 0, 47 }, /* IBM 8k/8k-l4 (Aurora Lite) */
130 { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 48 }, /* ASR-4810SAS (Hurricane */ 141 { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */
131 142 { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */
132 { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 49 }, /* Perc 320/DC*/ 143 { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */
133 { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 50 }, /* Adaptec 5400S (Mustang)*/ 144 { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-4810SAS (Hurricane */
134 { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 51 }, /* Adaptec 5400S (Mustang)*/ 145
135 { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 52 }, /* Dell PERC2/QC */ 146 { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/
136 { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 53 }, /* HP NetRAID-4M */ 147 { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/
137 148 { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 54 }, /* Adaptec 5400S (Mustang)*/
138 { 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 54 }, /* Dell Catchall */ 149 { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 55 }, /* Dell PERC2/QC */
139 { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 55 }, /* Legend Catchall */ 150 { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 56 }, /* HP NetRAID-4M */
140 { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 56 }, /* Adaptec Catch All */ 151
141 { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 57 }, /* Adaptec Rocket Catch All */ 152 { 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 57 }, /* Dell Catchall */
153 { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */
154 { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */
155 { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */
142 { 0,} 156 { 0,}
143}; 157};
144MODULE_DEVICE_TABLE(pci, aac_pci_tbl); 158MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
@@ -180,8 +194,9 @@ static struct aac_driver_ident aac_drivers[] = {
180 { aac_rkt_init, "aacraid", "ICP ", "ICP9047MA ", 1 }, /* ICP9047MA (Lancer) */ 194 { aac_rkt_init, "aacraid", "ICP ", "ICP9047MA ", 1 }, /* ICP9047MA (Lancer) */
181 { aac_rkt_init, "aacraid", "ICP ", "ICP9087MA ", 1 }, /* ICP9087MA (Lancer) */ 195 { aac_rkt_init, "aacraid", "ICP ", "ICP9087MA ", 1 }, /* ICP9087MA (Lancer) */
182 { aac_rkt_init, "aacraid", "ICP ", "ICP5085AU ", 1 }, /* ICP5085AU (Hurricane) */ 196 { aac_rkt_init, "aacraid", "ICP ", "ICP5085AU ", 1 }, /* ICP5085AU (Hurricane) */
183 { aac_rkt_init, "aacraid", "ICP ", "ICP9085LI ", 1 }, /* ICP9085LI (Marauder-X) */ 197 { aac_rx_init, "aacraid", "ICP ", "ICP9085LI ", 1 }, /* ICP9085LI (Marauder-X) */
184 { aac_rkt_init, "aacraid", "ICP ", "ICP5085BR ", 1 }, /* ICP5085BR (Marauder-E) */ 198 { aac_rx_init, "aacraid", "ICP ", "ICP5085BR ", 1 }, /* ICP5085BR (Marauder-E) */
199 { aac_rkt_init, "aacraid", "ICP ", "ICP9067MA ", 1 }, /* ICP9067MA (Intruder-6) */
185 { NULL , "aacraid", "ADAPTEC ", "Themisto ", 0, AAC_QUIRK_SLAVE }, /* Jupiter Platform */ 200 { NULL , "aacraid", "ADAPTEC ", "Themisto ", 0, AAC_QUIRK_SLAVE }, /* Jupiter Platform */
186 { aac_rkt_init, "aacraid", "ADAPTEC ", "Callisto ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */ 201 { aac_rkt_init, "aacraid", "ADAPTEC ", "Callisto ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */
187 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020SA ", 1 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */ 202 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020SA ", 1 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
@@ -195,10 +210,12 @@ static struct aac_driver_ident aac_drivers[] = {
195 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2240S ", 1 }, /* ASR-2240S (SabreExpress) */ 210 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2240S ", 1 }, /* ASR-2240S (SabreExpress) */
196 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4005SAS ", 1 }, /* ASR-4005SAS */ 211 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4005SAS ", 1 }, /* ASR-4005SAS */
197 { aac_rx_init, "ServeRAID","IBM ", "ServeRAID 8i ", 1 }, /* IBM 8i (AvonPark) */ 212 { aac_rx_init, "ServeRAID","IBM ", "ServeRAID 8i ", 1 }, /* IBM 8i (AvonPark) */
213 { aac_rkt_init, "ServeRAID","IBM ", "ServeRAID 8k-l8 ", 1 }, /* IBM 8k/8k-l8 (Aurora) */
214 { aac_rkt_init, "ServeRAID","IBM ", "ServeRAID 8k-l4 ", 1 }, /* IBM 8k/8k-l4 (Aurora Lite) */
198 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4000SAS ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */ 215 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4000SAS ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */
199 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4800SAS ", 1 }, /* ASR-4800SAS (Marauder-X) */ 216 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4800SAS ", 1 }, /* ASR-4800SAS (Marauder-X) */
200 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4805SAS ", 1 }, /* ASR-4805SAS (Marauder-E) */ 217 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4805SAS ", 1 }, /* ASR-4805SAS (Marauder-E) */
201 { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4810SAS ", 1 }, /* ASR-4810SAS (Hurricane) */ 218 { aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-4810SAS ", 1 }, /* ASR-4810SAS (Hurricane) */
202 219
203 { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/ 220 { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
204 { aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/ 221 { aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
@@ -839,11 +856,12 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
839 856
840 return 0; 857 return 0;
841 858
842out_deinit: 859 out_deinit:
843 kill_proc(aac->thread_pid, SIGKILL, 0); 860 kill_proc(aac->thread_pid, SIGKILL, 0);
844 wait_for_completion(&aac->aif_completion); 861 wait_for_completion(&aac->aif_completion);
845 862
846 aac_send_shutdown(aac); 863 aac_send_shutdown(aac);
864 aac_adapter_disable_int(aac);
847 fib_map_free(aac); 865 fib_map_free(aac);
848 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); 866 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
849 kfree(aac->queues); 867 kfree(aac->queues);
@@ -860,6 +878,13 @@ out_deinit:
860 return error; 878 return error;
861} 879}
862 880
881static void aac_shutdown(struct pci_dev *dev)
882{
883 struct Scsi_Host *shost = pci_get_drvdata(dev);
884 struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
885 aac_send_shutdown(aac);
886}
887
863static void __devexit aac_remove_one(struct pci_dev *pdev) 888static void __devexit aac_remove_one(struct pci_dev *pdev)
864{ 889{
865 struct Scsi_Host *shost = pci_get_drvdata(pdev); 890 struct Scsi_Host *shost = pci_get_drvdata(pdev);
@@ -871,6 +896,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
871 wait_for_completion(&aac->aif_completion); 896 wait_for_completion(&aac->aif_completion);
872 897
873 aac_send_shutdown(aac); 898 aac_send_shutdown(aac);
899 aac_adapter_disable_int(aac);
874 fib_map_free(aac); 900 fib_map_free(aac);
875 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, 901 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,
876 aac->comm_phys); 902 aac->comm_phys);
@@ -891,14 +917,15 @@ static struct pci_driver aac_pci_driver = {
891 .id_table = aac_pci_tbl, 917 .id_table = aac_pci_tbl,
892 .probe = aac_probe_one, 918 .probe = aac_probe_one,
893 .remove = __devexit_p(aac_remove_one), 919 .remove = __devexit_p(aac_remove_one),
920 .shutdown = aac_shutdown,
894}; 921};
895 922
896static int __init aac_init(void) 923static int __init aac_init(void)
897{ 924{
898 int error; 925 int error;
899 926
900 printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n", 927 printk(KERN_INFO "Adaptec %s driver (%s)\n",
901 AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE); 928 AAC_DRIVERNAME, aac_driver_version);
902 929
903 error = pci_module_init(&aac_pci_driver); 930 error = pci_module_init(&aac_pci_driver);
904 if (error) 931 if (error)
@@ -909,6 +936,7 @@ static int __init aac_init(void)
909 printk(KERN_WARNING 936 printk(KERN_WARNING
910 "aacraid: unable to register \"aac\" device.\n"); 937 "aacraid: unable to register \"aac\" device.\n");
911 } 938 }
939
912 return 0; 940 return 0;
913} 941}
914 942
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index 7d68b7825137..557287a0b80b 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -88,6 +88,16 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs)
88} 88}
89 89
90/** 90/**
91 * aac_rkt_disable_interrupt - Disable interrupts
92 * @dev: Adapter
93 */
94
95static void aac_rkt_disable_interrupt(struct aac_dev *dev)
96{
97 rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
98}
99
100/**
91 * rkt_sync_cmd - send a command and wait 101 * rkt_sync_cmd - send a command and wait
92 * @dev: Adapter 102 * @dev: Adapter
93 * @command: Command to execute 103 * @command: Command to execute
@@ -412,10 +422,19 @@ int aac_rkt_init(struct aac_dev *dev)
412 * Fill in the function dispatch table. 422 * Fill in the function dispatch table.
413 */ 423 */
414 dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter; 424 dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter;
425 dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt;
415 dev->a_ops.adapter_notify = aac_rkt_notify_adapter; 426 dev->a_ops.adapter_notify = aac_rkt_notify_adapter;
416 dev->a_ops.adapter_sync_cmd = rkt_sync_cmd; 427 dev->a_ops.adapter_sync_cmd = rkt_sync_cmd;
417 dev->a_ops.adapter_check_health = aac_rkt_check_health; 428 dev->a_ops.adapter_check_health = aac_rkt_check_health;
418 429
430 /*
431 * First clear out all interrupts. Then enable the one's that we
432 * can handle.
433 */
434 rkt_writeb(dev, MUnit.OIMR, 0xff);
435 rkt_writel(dev, MUnit.ODR, 0xffffffff);
436 rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
437
419 if (aac_init_adapter(dev) == NULL) 438 if (aac_init_adapter(dev) == NULL)
420 goto error_irq; 439 goto error_irq;
421 /* 440 /*
@@ -438,6 +457,7 @@ error_kfree:
438 kfree(dev->queues); 457 kfree(dev->queues);
439 458
440error_irq: 459error_irq:
460 rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
441 free_irq(dev->scsi_host_ptr->irq, (void *)dev); 461 free_irq(dev->scsi_host_ptr->irq, (void *)dev);
442 462
443error_iounmap: 463error_iounmap:
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 1ff25f49fada..a8459faf87ca 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -88,6 +88,16 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
88} 88}
89 89
90/** 90/**
91 * aac_rx_disable_interrupt - Disable interrupts
92 * @dev: Adapter
93 */
94
95static void aac_rx_disable_interrupt(struct aac_dev *dev)
96{
97 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
98}
99
100/**
91 * rx_sync_cmd - send a command and wait 101 * rx_sync_cmd - send a command and wait
92 * @dev: Adapter 102 * @dev: Adapter
93 * @command: Command to execute 103 * @command: Command to execute
@@ -412,10 +422,19 @@ int aac_rx_init(struct aac_dev *dev)
412 * Fill in the function dispatch table. 422 * Fill in the function dispatch table.
413 */ 423 */
414 dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; 424 dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
425 dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;
415 dev->a_ops.adapter_notify = aac_rx_notify_adapter; 426 dev->a_ops.adapter_notify = aac_rx_notify_adapter;
416 dev->a_ops.adapter_sync_cmd = rx_sync_cmd; 427 dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
417 dev->a_ops.adapter_check_health = aac_rx_check_health; 428 dev->a_ops.adapter_check_health = aac_rx_check_health;
418 429
430 /*
431 * First clear out all interrupts. Then enable the one's that we
432 * can handle.
433 */
434 rx_writeb(dev, MUnit.OIMR, 0xff);
435 rx_writel(dev, MUnit.ODR, 0xffffffff);
436 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
437
419 if (aac_init_adapter(dev) == NULL) 438 if (aac_init_adapter(dev) == NULL)
420 goto error_irq; 439 goto error_irq;
421 /* 440 /*
@@ -438,6 +457,7 @@ error_kfree:
438 kfree(dev->queues); 457 kfree(dev->queues);
439 458
440error_irq: 459error_irq:
460 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
441 free_irq(dev->scsi_host_ptr->irq, (void *)dev); 461 free_irq(dev->scsi_host_ptr->irq, (void *)dev);
442 462
443error_iounmap: 463error_iounmap:
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index 0680249ab861..3900abc5850d 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -82,6 +82,16 @@ static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
82} 82}
83 83
84/** 84/**
85 * aac_sa_disable_interrupt - disable interrupt
86 * @dev: Which adapter to enable.
87 */
88
89static void aac_sa_disable_interrupt (struct aac_dev *dev)
90{
91 sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
92}
93
94/**
85 * aac_sa_notify_adapter - handle adapter notification 95 * aac_sa_notify_adapter - handle adapter notification
86 * @dev: Adapter that notification is for 96 * @dev: Adapter that notification is for
87 * @event: Event to notidy 97 * @event: Event to notidy
@@ -214,9 +224,8 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command,
214 224
215static void aac_sa_interrupt_adapter (struct aac_dev *dev) 225static void aac_sa_interrupt_adapter (struct aac_dev *dev)
216{ 226{
217 u32 ret;
218 sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, 227 sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
219 &ret, NULL, NULL, NULL, NULL); 228 NULL, NULL, NULL, NULL, NULL);
220} 229}
221 230
222/** 231/**
@@ -352,10 +361,18 @@ int aac_sa_init(struct aac_dev *dev)
352 */ 361 */
353 362
354 dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter; 363 dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
364 dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
355 dev->a_ops.adapter_notify = aac_sa_notify_adapter; 365 dev->a_ops.adapter_notify = aac_sa_notify_adapter;
356 dev->a_ops.adapter_sync_cmd = sa_sync_cmd; 366 dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
357 dev->a_ops.adapter_check_health = aac_sa_check_health; 367 dev->a_ops.adapter_check_health = aac_sa_check_health;
358 368
369 /*
370 * First clear out all interrupts. Then enable the one's that
371 * we can handle.
372 */
373 sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
374 sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 |
375 DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
359 376
360 if(aac_init_adapter(dev) == NULL) 377 if(aac_init_adapter(dev) == NULL)
361 goto error_irq; 378 goto error_irq;
@@ -381,6 +398,7 @@ error_kfree:
381 kfree(dev->queues); 398 kfree(dev->queues);
382 399
383error_irq: 400error_irq:
401 sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
384 free_irq(dev->scsi_host_ptr->irq, (void *)dev); 402 free_irq(dev->scsi_host_ptr->irq, (void *)dev);
385 403
386error_iounmap: 404error_iounmap: