diff options
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 327 | ||||
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 55 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 20 | ||||
-rw-r--r-- | drivers/scsi/aacraid/comminit.c | 4 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 20 | ||||
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 106 | ||||
-rw-r--r-- | drivers/scsi/aacraid/rkt.c | 20 | ||||
-rw-r--r-- | drivers/scsi/aacraid/rx.c | 20 | ||||
-rw-r--r-- | drivers/scsi/aacraid/sa.c | 22 |
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 { static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); +static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg); static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); #ifdef AAC_DETAILED_STATUS_INFO static char *aac_get_status_string(u32 status); @@ -348,6 +349,27 @@ static void aac_io_done(struct scsi_cmnd * scsicmd) spin_unlock_irqrestore(host->host_lock, cpu_flags); } +static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) +{ + void *buf; + unsigned int transfer_len; + struct scatterlist *sg = scsicmd->request_buffer; + + if (scsicmd->use_sg) { + buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + transfer_len = min(sg->length, len + offset); + } else { + buf = scsicmd->request_buffer; + transfer_len = min(scsicmd->request_bufflen, len + offset); + } + + memcpy(buf + offset, data, transfer_len - offset); + + if (scsicmd->use_sg) + kunmap_atomic(buf - sg->offset, KM_IRQ0); + +} + static void get_container_name_callback(void *context, struct fib * fibptr) { struct aac_get_name_resp * get_name_reply; @@ -363,18 +385,22 @@ static void get_container_name_callback(void *context, struct fib * fibptr) /* Failure is irrelevant, using default value instead */ if ((le32_to_cpu(get_name_reply->status) == CT_OK) && (get_name_reply->data[0] != '\0')) { - int count; - char * dp; - char * sp = get_name_reply->data; + char *sp = get_name_reply->data; sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0'; while (*sp == ' ') ++sp; - count = sizeof(((struct inquiry_data *)NULL)->inqd_pid); - dp = ((struct inquiry_data *)scsicmd->request_buffer)->inqd_pid; - if (*sp) do { - *dp++ = (*sp) ? *sp++ : ' '; - } while (--count > 0); + if (*sp) { + char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; + int count = sizeof(d); + char *dp = d; + do { + *dp++ = (*sp) ? *sp++ : ' '; + } while (--count > 0); + aac_internal_transfer(scsicmd, d, + offsetof(struct inquiry_data, inqd_pid), sizeof(d)); + } } + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; fib_complete(fibptr); @@ -777,34 +803,36 @@ int aac_get_adapter_info(struct aac_dev* dev) /* * 57 scatter gather elements */ - dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - - sizeof(struct aac_fibhdr) - - sizeof(struct aac_write) + sizeof(struct sgmap)) / - sizeof(struct sgmap); - if (dev->dac_support) { - /* - * 38 scatter gather elements - */ - dev->scsi_host_ptr->sg_tablesize = - (dev->max_fib_size - + if (!(dev->raw_io_interface)) { + dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - sizeof(struct aac_fibhdr) - - sizeof(struct aac_write64) + - sizeof(struct sgmap64)) / - sizeof(struct sgmap64); - } - dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; - if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { - /* - * Worst case size that could cause sg overflow when - * we break up SG elements that are larger than 64KB. - * Would be nice if we could tell the SCSI layer what - * the maximum SG element size can be. Worst case is - * (sg_tablesize-1) 4KB elements with one 64KB - * element. - * 32bit -> 468 or 238KB 64bit -> 424 or 212KB - */ - dev->scsi_host_ptr->max_sectors = - (dev->scsi_host_ptr->sg_tablesize * 8) + 112; + sizeof(struct aac_write) + sizeof(struct sgmap)) / + sizeof(struct sgmap); + if (dev->dac_support) { + /* + * 38 scatter gather elements + */ + dev->scsi_host_ptr->sg_tablesize = + (dev->max_fib_size - + sizeof(struct aac_fibhdr) - + sizeof(struct aac_write64) + + sizeof(struct sgmap64)) / + sizeof(struct sgmap64); + } + dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; + if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { + /* + * Worst case size that could cause sg overflow when + * we break up SG elements that are larger than 64KB. + * Would be nice if we could tell the SCSI layer what + * the maximum SG element size can be. Worst case is + * (sg_tablesize-1) 4KB elements with one 64KB + * element. + * 32bit -> 468 or 238KB 64bit -> 424 or 212KB + */ + dev->scsi_host_ptr->max_sectors = + (dev->scsi_host_ptr->sg_tablesize * 8) + 112; + } } fib_complete(fibptr); @@ -814,12 +842,11 @@ int aac_get_adapter_info(struct aac_dev* dev) } -static void read_callback(void *context, struct fib * fibptr) +static void io_callback(void *context, struct fib * fibptr) { struct aac_dev *dev; struct aac_read_reply *readreply; struct scsi_cmnd *scsicmd; - u32 lba; u32 cid; scsicmd = (struct scsi_cmnd *) context; @@ -827,8 +854,7 @@ static void read_callback(void *context, struct fib * fibptr) dev = (struct aac_dev *)scsicmd->device->host->hostdata; cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); - lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; - dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); + 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)); if (fibptr == NULL) BUG(); @@ -847,7 +873,7 @@ static void read_callback(void *context, struct fib * fibptr) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; else { #ifdef AAC_DETAILED_STATUS_INFO - printk(KERN_WARNING "read_callback: io failed, status = %d\n", + printk(KERN_WARNING "io_callback: io failed, status = %d\n", le32_to_cpu(readreply->status)); #endif 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) aac_io_done(scsicmd); } -static void write_callback(void *context, struct fib * fibptr) -{ - struct aac_dev *dev; - struct aac_write_reply *writereply; - struct scsi_cmnd *scsicmd; - u32 lba; - u32 cid; - - scsicmd = (struct scsi_cmnd *) context; - dev = (struct aac_dev *)scsicmd->device->host->hostdata; - cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); - - lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; - dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); - if (fibptr == NULL) - BUG(); - - if(scsicmd->use_sg) - pci_unmap_sg(dev->pdev, - (struct scatterlist *)scsicmd->buffer, - scsicmd->use_sg, - scsicmd->sc_data_direction); - else if(scsicmd->request_bufflen) - pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle, - scsicmd->request_bufflen, - scsicmd->sc_data_direction); - - writereply = (struct aac_write_reply *) fib_data(fibptr); - if (le32_to_cpu(writereply->status) == ST_OK) - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; - else { - printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status); - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; - set_sense((u8 *) &dev->fsa_dev[cid].sense_data, - HARDWARE_ERROR, - SENCODE_INTERNAL_TARGET_FAILURE, - ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, - 0, 0); - memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, - sizeof(struct sense_data)); - } - - fib_complete(fibptr); - fib_free(fibptr); - aac_io_done(scsicmd); -} - static int aac_read(struct scsi_cmnd * scsicmd, int cid) { u32 lba; @@ -954,7 +933,32 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) fib_init(cmd_fibcontext); - if (dev->dac_support == 1) { + if (dev->raw_io_interface) { + struct aac_raw_io *readcmd; + readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); + readcmd->block[0] = cpu_to_le32(lba); + readcmd->block[1] = 0; + readcmd->count = cpu_to_le32(count<<9); + readcmd->cid = cpu_to_le16(cid); + readcmd->flags = cpu_to_le16(1); + readcmd->bpTotal = 0; + readcmd->bpComplete = 0; + + aac_build_sgraw(scsicmd, &readcmd->sg); + fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); + if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) + BUG(); + /* + * Now send the Fib to the adapter + */ + status = fib_send(ContainerRawIo, + cmd_fibcontext, + fibsize, + FsaNormal, + 0, 1, + (fib_callback) io_callback, + (void *) scsicmd); + } else if (dev->dac_support == 1) { struct aac_read64 *readcmd; readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); readcmd->command = cpu_to_le32(VM_CtHostRead64); @@ -968,7 +972,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) fibsize = sizeof(struct aac_read64) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentry64)); - BUG_ON (fibsize > (sizeof(struct hw_fib) - + BUG_ON (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))); /* * Now send the Fib to the adapter @@ -978,7 +982,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) fibsize, FsaNormal, 0, 1, - (fib_callback) read_callback, + (fib_callback) io_callback, (void *) scsicmd); } else { struct aac_read *readcmd; @@ -1002,7 +1006,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) fibsize, FsaNormal, 0, 1, - (fib_callback) read_callback, + (fib_callback) io_callback, (void *) scsicmd); } @@ -1061,7 +1065,32 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) } fib_init(cmd_fibcontext); - if(dev->dac_support == 1) { + if (dev->raw_io_interface) { + struct aac_raw_io *writecmd; + writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); + writecmd->block[0] = cpu_to_le32(lba); + writecmd->block[1] = 0; + writecmd->count = cpu_to_le32(count<<9); + writecmd->cid = cpu_to_le16(cid); + writecmd->flags = 0; + writecmd->bpTotal = 0; + writecmd->bpComplete = 0; + + aac_build_sgraw(scsicmd, &writecmd->sg); + fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); + if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) + BUG(); + /* + * Now send the Fib to the adapter + */ + status = fib_send(ContainerRawIo, + cmd_fibcontext, + fibsize, + FsaNormal, + 0, 1, + (fib_callback) io_callback, + (void *) scsicmd); + } else if (dev->dac_support == 1) { struct aac_write64 *writecmd; writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); writecmd->command = cpu_to_le32(VM_CtHostWrite64); @@ -1085,7 +1114,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) fibsize, FsaNormal, 0, 1, - (fib_callback) write_callback, + (fib_callback) io_callback, (void *) scsicmd); } else { struct aac_write *writecmd; @@ -1111,7 +1140,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) fibsize, FsaNormal, 0, 1, - (fib_callback) write_callback, + (fib_callback) io_callback, (void *) scsicmd); } @@ -1340,44 +1369,45 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) switch (scsicmd->cmnd[0]) { case INQUIRY: { - struct inquiry_data *inq_data_ptr; + struct inquiry_data inq_data; dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id)); - inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer; - memset(inq_data_ptr, 0, sizeof (struct inquiry_data)); + memset(&inq_data, 0, sizeof (struct inquiry_data)); - inq_data_ptr->inqd_ver = 2; /* claim compliance to SCSI-2 */ - inq_data_ptr->inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ - 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 */ - inq_data_ptr->inqd_len = 31; + inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ + inq_data.inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ + 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 */ + inq_data.inqd_len = 31; /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ - inq_data_ptr->inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */ + inq_data.inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */ /* * Set the Vendor, Product, and Revision Level * see: <vendor>.c i.e. aac.c */ if (scsicmd->device->id == host->this_id) { - setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), (sizeof(container_types)/sizeof(char *))); - inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */ + setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *))); + inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ + aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); return 0; } - setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr[cid].type); - inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ + setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); + inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ + aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); return aac_get_container_name(scsicmd, cid); } case READ_CAPACITY: { u32 capacity; - char *cp; + char cp[8]; dprintk((KERN_DEBUG "READ CAPACITY command.\n")); if (fsa_dev_ptr[cid].size <= 0x100000000LL) capacity = fsa_dev_ptr[cid].size - 1; else capacity = (u32)-1; - cp = scsicmd->request_buffer; + cp[0] = (capacity >> 24) & 0xff; cp[1] = (capacity >> 16) & 0xff; cp[2] = (capacity >> 8) & 0xff; @@ -1386,6 +1416,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) cp[5] = 0; cp[6] = 2; cp[7] = 0; + aac_internal_transfer(scsicmd, cp, 0, sizeof(cp)); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); @@ -1395,15 +1426,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) case MODE_SENSE: { - char *mode_buf; + char mode_buf[4]; dprintk((KERN_DEBUG "MODE SENSE command.\n")); - mode_buf = scsicmd->request_buffer; mode_buf[0] = 3; /* Mode data length */ mode_buf[1] = 0; /* Medium type - default */ mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */ mode_buf[3] = 0; /* Block descriptor length */ + aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf)); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); @@ -1411,10 +1442,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) } case MODE_SENSE_10: { - char *mode_buf; + char mode_buf[8]; dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n")); - mode_buf = scsicmd->request_buffer; mode_buf[0] = 0; /* Mode data length (MSB) */ mode_buf[1] = 6; /* Mode data length (LSB) */ mode_buf[2] = 0; /* Medium type - default */ @@ -1423,6 +1453,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) mode_buf[5] = 0; /* reserved */ mode_buf[6] = 0; /* Block descriptor length (MSB) */ mode_buf[7] = 0; /* Block descriptor length (LSB) */ + aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf)); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); @@ -1894,7 +1925,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) srbcmd->id = cpu_to_le32(scsicmd->device->id); srbcmd->lun = cpu_to_le32(scsicmd->device->lun); srbcmd->flags = cpu_to_le32(flag); - timeout = (scsicmd->timeout-jiffies)/HZ; + timeout = scsicmd->timeout_per_command/HZ; if(timeout == 0){ timeout = 1; } @@ -2077,6 +2108,76 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p return byte_count; } +static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg) +{ + struct Scsi_Host *host = scsicmd->device->host; + struct aac_dev *dev = (struct aac_dev *)host->hostdata; + unsigned long byte_count = 0; + + // Get rid of old data + psg->count = 0; + psg->sg[0].next = 0; + psg->sg[0].prev = 0; + psg->sg[0].addr[0] = 0; + psg->sg[0].addr[1] = 0; + psg->sg[0].count = 0; + psg->sg[0].flags = 0; + if (scsicmd->use_sg) { + struct scatterlist *sg; + int i; + int sg_count; + sg = (struct scatterlist *) scsicmd->request_buffer; + + sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg, + scsicmd->sc_data_direction); + + for (i = 0; i < sg_count; i++) { + int count = sg_dma_len(sg); + u64 addr = sg_dma_address(sg); + psg->sg[i].next = 0; + psg->sg[i].prev = 0; + psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32)); + psg->sg[i].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff)); + psg->sg[i].count = cpu_to_le32(count); + psg->sg[i].flags = 0; + byte_count += count; + sg++; + } + psg->count = cpu_to_le32(sg_count); + /* hba wants the size to be exact */ + if(byte_count > scsicmd->request_bufflen){ + u32 temp = le32_to_cpu(psg->sg[i-1].count) - + (byte_count - scsicmd->request_bufflen); + psg->sg[i-1].count = cpu_to_le32(temp); + byte_count = scsicmd->request_bufflen; + } + /* Check for command underflow */ + if(scsicmd->underflow && (byte_count < scsicmd->underflow)){ + printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n", + byte_count, scsicmd->underflow); + } + } + else if(scsicmd->request_bufflen) { + int count; + u64 addr; + scsicmd->SCp.dma_handle = pci_map_single(dev->pdev, + scsicmd->request_buffer, + scsicmd->request_bufflen, + scsicmd->sc_data_direction); + addr = scsicmd->SCp.dma_handle; + count = scsicmd->request_bufflen; + psg->count = cpu_to_le32(1); + psg->sg[0].next = 0; + psg->sg[0].prev = 0; + psg->sg[0].addr[1] = cpu_to_le32((u32)(addr>>32)); + psg->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff)); + psg->sg[0].count = cpu_to_le32(count); + psg->sg[0].flags = 0; + byte_count = scsicmd->request_bufflen; + } + return byte_count; +} + #ifdef AAC_DETAILED_STATUS_INFO struct 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 { u32 count; /* Length. */ }; +struct sgentryraw { + __le32 next; /* reserved for F/W use */ + __le32 prev; /* reserved for F/W use */ + __le32 addr[2]; + __le32 count; + __le32 flags; /* reserved for F/W use */ +}; + +struct user_sgentryraw { + u32 next; /* reserved for F/W use */ + u32 prev; /* reserved for F/W use */ + u32 addr[2]; + u32 count; + u32 flags; /* reserved for F/W use */ +}; + /* * SGMAP * @@ -137,6 +153,16 @@ struct user_sgmap64 { struct user_sgentry64 sg[1]; }; +struct sgmapraw { + __le32 count; + struct sgentryraw sg[1]; +}; + +struct user_sgmapraw { + u32 count; + struct user_sgentryraw sg[1]; +}; + struct creation_info { u8 buildnum; /* e.g., 588 */ @@ -351,6 +377,7 @@ struct hw_fib { */ #define ContainerCommand 500 #define ContainerCommand64 501 +#define ContainerRawIo 502 /* * Cluster Commands */ @@ -456,6 +483,7 @@ struct adapter_ops { void (*adapter_interrupt)(struct aac_dev *dev); void (*adapter_notify)(struct aac_dev *dev, u32 event); + void (*adapter_disable_int)(struct aac_dev *dev); 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); int (*adapter_check_health)(struct aac_dev *dev); }; @@ -981,6 +1009,9 @@ struct aac_dev u8 nondasd_support; u8 dac_support; u8 raid_scsi_mode; + /* macro side-effects BEWARE */ +# define raw_io_interface \ + init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) u8 printf_enabled; }; @@ -990,6 +1021,9 @@ struct aac_dev #define aac_adapter_notify(dev, event) \ (dev)->a_ops.adapter_notify(dev, event) +#define aac_adapter_disable_int(dev) \ + (dev)->a_ops.adapter_disable_int(dev) + #define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \ (dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) @@ -1156,6 +1190,17 @@ struct aac_write_reply __le32 committed; }; +struct aac_raw_io +{ + __le32 block[2]; + __le32 count; + __le16 cid; + __le16 flags; /* 00 W, 01 R */ + __le16 bpTotal; /* reserved for F/W use */ + __le16 bpComplete; /* reserved for F/W use */ + struct sgmapraw sg; +}; + #define CT_FLUSH_CACHE 129 struct aac_synchronize { __le32 command; /* VM_ContainerConfig */ @@ -1196,7 +1241,7 @@ struct aac_srb }; /* - * This and assocated data structs are used by the + * This and associated data structs are used by the * ioctl caller and are in cpu order. */ struct user_aac_srb @@ -1508,11 +1553,12 @@ struct fib_ioctl struct revision { - u32 compat; - u32 version; - u32 build; + __le32 compat; + __le32 version; + __le32 build; }; + /* * Ugly - non Linux like ioctl coding for back compat. */ @@ -1733,3 +1779,4 @@ int aac_get_adapter_info(struct aac_dev* dev); int aac_send_shutdown(struct aac_dev *dev); extern int numacb; extern int acbsize; +extern 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: kfree(fib->hw_fib); kfree(fib); status = 0; - fibctx->jiffies = jiffies/HZ; } else { spin_unlock_irqrestore(&dev->fib_lock, flags); if (f.wait) { @@ -302,6 +301,7 @@ return_fib: status = -EAGAIN; } } + fibctx->jiffies = jiffies/HZ; return status; } @@ -405,10 +405,20 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg) static int check_revision(struct aac_dev *dev, void __user *arg) { struct revision response; - - response.compat = 1; - response.version = le32_to_cpu(dev->adapter_info.kernelrev); - response.build = le32_to_cpu(dev->adapter_info.kernelbuild); + char *driver_version = aac_driver_version; + u32 version; + + response.compat = cpu_to_le32(1); + version = (simple_strtol(driver_version, + &driver_version, 10) << 24) | 0x00000400; + version += simple_strtol(driver_version + 1, &driver_version, 10) << 16; + version += simple_strtol(driver_version + 1, NULL, 10); + response.version = cpu_to_le32(version); +# if (defined(AAC_DRIVER_BUILD)) + response.build = cpu_to_le32(AAC_DRIVER_BUILD); +# else + response.build = cpu_to_le32(9999); +# endif if (copy_to_user(arg, &response, sizeof(response))) 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 @@ #include "aacraid.h" -struct aac_common aac_config; +struct aac_common aac_config = { + .irq_mod = 1 +}; static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign) { 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) static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify) { struct aac_queue * q; + unsigned long idx; /* * 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 */ q = &dev->queues->queue[qid]; - - *index = le32_to_cpu(*(q->headers.producer)); - if ((*index - 2) == le32_to_cpu(*(q->headers.consumer))) + + idx = *index = le32_to_cpu(*(q->headers.producer)); + /* Interrupt Moderation, only interrupt for first two entries */ + if (idx != le32_to_cpu(*(q->headers.consumer))) { + if (--idx == 0) { + if (qid == AdapHighCmdQueue) + idx = ADAP_HIGH_CMD_ENTRIES; + else if (qid == AdapNormCmdQueue) + idx = ADAP_NORM_CMD_ENTRIES; + else if (qid == AdapHighRespQueue) + idx = ADAP_HIGH_RESP_ENTRIES; + else if (qid == AdapNormRespQueue) + idx = ADAP_NORM_RESP_ENTRIES; + } + if (idx != le32_to_cpu(*(q->headers.consumer))) *nonotify = 1; + } if (qid == AdapHighCmdQueue) { 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 @@ * Abstract: Linux Driver entry module for Adaptec RAID Array Controller */ -#define AAC_DRIVER_VERSION "1.1.2-lk2" -#define AAC_DRIVER_BUILD_DATE __DATE__ +#define AAC_DRIVER_VERSION "1.1-4" +#ifndef AAC_DRIVER_BRANCH +#define AAC_DRIVER_BRANCH "" +#endif +#define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__ #define AAC_DRIVERNAME "aacraid" #include <linux/compat.h> @@ -58,16 +61,24 @@ #include "aacraid.h" +#ifdef AAC_DRIVER_BUILD +#define _str(x) #x +#define str(x) _str(x) +#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH +#else +#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION AAC_DRIVER_BRANCH " " AAC_DRIVER_BUILD_DATE +#endif MODULE_AUTHOR("Red Hat Inc and Adaptec"); MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, " "Adaptec Advanced Raid Products, " "and HP NetRAID-4M SCSI driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(AAC_DRIVER_VERSION); +MODULE_VERSION(AAC_DRIVER_FULL_VERSION); static LIST_HEAD(aac_devices); static int aac_cfg_major = -1; +char aac_driver_version[] = AAC_DRIVER_FULL_VERSION; /* * 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[] = { { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */ { 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */ { 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */ - { 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 32 }, /* Themisto Jupiter Platform */ - { 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 32 }, /* Themisto Jupiter Platform */ - { 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 33 }, /* Callisto Jupiter Platform */ - { 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 34 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */ - { 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 35 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */ - { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 36 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */ - { 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 37 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */ - { 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 38 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */ - { 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 39 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */ - { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 40 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ - { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 41 }, /* AAR-2610SA PCI SATA 6ch */ - { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 42 }, /* ASR-2240S (SabreExpress) */ - { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 43 }, /* ASR-4005SAS */ - { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 44 }, /* IBM 8i (AvonPark) */ - { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 44 }, /* IBM 8i (AvonPark Lite) */ - { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 45 }, /* ASR-4000SAS (BlackBird) */ - { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 46 }, /* ASR-4800SAS (Marauder-X) */ - { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 47 }, /* ASR-4805SAS (Marauder-E) */ - { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 48 }, /* ASR-4810SAS (Hurricane */ - - { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 49 }, /* Perc 320/DC*/ - { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 50 }, /* Adaptec 5400S (Mustang)*/ - { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 51 }, /* Adaptec 5400S (Mustang)*/ - { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 52 }, /* Dell PERC2/QC */ - { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 53 }, /* HP NetRAID-4M */ - - { 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 54 }, /* Dell Catchall */ - { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 55 }, /* Legend Catchall */ - { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 56 }, /* Adaptec Catch All */ - { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 57 }, /* Adaptec Rocket Catch All */ + { 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 }, /* ICP9067MA (Intruder-6) */ + { 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 33 }, /* Themisto Jupiter Platform */ + { 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 33 }, /* Themisto Jupiter Platform */ + { 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 34 }, /* Callisto Jupiter Platform */ + { 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 35 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */ + { 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 36 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */ + { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 37 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */ + { 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 38 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */ + { 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 39 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */ + { 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 40 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */ + { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 41 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ + { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 42 }, /* AAR-2610SA PCI SATA 6ch */ + { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 43 }, /* ASR-2240S (SabreExpress) */ + { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005SAS */ + { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 45 }, /* IBM 8i (AvonPark) */ + { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 45 }, /* IBM 8i (AvonPark Lite) */ + { 0x9005, 0x0286, 0x1014, 0x9580, 0, 0, 46 }, /* IBM 8k/8k-l8 (Aurora) */ + { 0x9005, 0x0286, 0x1014, 0x9540, 0, 0, 47 }, /* IBM 8k/8k-l4 (Aurora Lite) */ + { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */ + { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */ + { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */ + { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-4810SAS (Hurricane */ + + { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/ + { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/ + { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 54 }, /* Adaptec 5400S (Mustang)*/ + { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 55 }, /* Dell PERC2/QC */ + { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 56 }, /* HP NetRAID-4M */ + + { 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 57 }, /* Dell Catchall */ + { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */ + { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */ + { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */ { 0,} }; MODULE_DEVICE_TABLE(pci, aac_pci_tbl); @@ -180,8 +194,9 @@ static struct aac_driver_ident aac_drivers[] = { { aac_rkt_init, "aacraid", "ICP ", "ICP9047MA ", 1 }, /* ICP9047MA (Lancer) */ { aac_rkt_init, "aacraid", "ICP ", "ICP9087MA ", 1 }, /* ICP9087MA (Lancer) */ { aac_rkt_init, "aacraid", "ICP ", "ICP5085AU ", 1 }, /* ICP5085AU (Hurricane) */ - { aac_rkt_init, "aacraid", "ICP ", "ICP9085LI ", 1 }, /* ICP9085LI (Marauder-X) */ - { aac_rkt_init, "aacraid", "ICP ", "ICP5085BR ", 1 }, /* ICP5085BR (Marauder-E) */ + { aac_rx_init, "aacraid", "ICP ", "ICP9085LI ", 1 }, /* ICP9085LI (Marauder-X) */ + { aac_rx_init, "aacraid", "ICP ", "ICP5085BR ", 1 }, /* ICP5085BR (Marauder-E) */ + { aac_rkt_init, "aacraid", "ICP ", "ICP9067MA ", 1 }, /* ICP9067MA (Intruder-6) */ { NULL , "aacraid", "ADAPTEC ", "Themisto ", 0, AAC_QUIRK_SLAVE }, /* Jupiter Platform */ { aac_rkt_init, "aacraid", "ADAPTEC ", "Callisto ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */ { 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[] = { { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2240S ", 1 }, /* ASR-2240S (SabreExpress) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4005SAS ", 1 }, /* ASR-4005SAS */ { aac_rx_init, "ServeRAID","IBM ", "ServeRAID 8i ", 1 }, /* IBM 8i (AvonPark) */ + { aac_rkt_init, "ServeRAID","IBM ", "ServeRAID 8k-l8 ", 1 }, /* IBM 8k/8k-l8 (Aurora) */ + { aac_rkt_init, "ServeRAID","IBM ", "ServeRAID 8k-l4 ", 1 }, /* IBM 8k/8k-l4 (Aurora Lite) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4000SAS ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4800SAS ", 1 }, /* ASR-4800SAS (Marauder-X) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4805SAS ", 1 }, /* ASR-4805SAS (Marauder-E) */ - { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4810SAS ", 1 }, /* ASR-4810SAS (Hurricane) */ + { aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-4810SAS ", 1 }, /* ASR-4810SAS (Hurricane) */ { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/ { 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, return 0; -out_deinit: + out_deinit: kill_proc(aac->thread_pid, SIGKILL, 0); wait_for_completion(&aac->aif_completion); aac_send_shutdown(aac); + aac_adapter_disable_int(aac); fib_map_free(aac); pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); kfree(aac->queues); @@ -860,6 +878,13 @@ out_deinit: return error; } +static void aac_shutdown(struct pci_dev *dev) +{ + struct Scsi_Host *shost = pci_get_drvdata(dev); + struct aac_dev *aac = (struct aac_dev *)shost->hostdata; + aac_send_shutdown(aac); +} + static void __devexit aac_remove_one(struct pci_dev *pdev) { struct Scsi_Host *shost = pci_get_drvdata(pdev); @@ -871,6 +896,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev) wait_for_completion(&aac->aif_completion); aac_send_shutdown(aac); + aac_adapter_disable_int(aac); fib_map_free(aac); pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); @@ -891,14 +917,15 @@ static struct pci_driver aac_pci_driver = { .id_table = aac_pci_tbl, .probe = aac_probe_one, .remove = __devexit_p(aac_remove_one), + .shutdown = aac_shutdown, }; static int __init aac_init(void) { int error; - printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n", - AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE); + printk(KERN_INFO "Adaptec %s driver (%s)\n", + AAC_DRIVERNAME, aac_driver_version); error = pci_module_init(&aac_pci_driver); if (error) @@ -909,6 +936,7 @@ static int __init aac_init(void) printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n"); } + return 0; } 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) } /** + * aac_rkt_disable_interrupt - Disable interrupts + * @dev: Adapter + */ + +static void aac_rkt_disable_interrupt(struct aac_dev *dev) +{ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); +} + +/** * rkt_sync_cmd - send a command and wait * @dev: Adapter * @command: Command to execute @@ -412,10 +422,19 @@ int aac_rkt_init(struct aac_dev *dev) * Fill in the function dispatch table. */ dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter; + dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt; dev->a_ops.adapter_notify = aac_rkt_notify_adapter; dev->a_ops.adapter_sync_cmd = rkt_sync_cmd; dev->a_ops.adapter_check_health = aac_rkt_check_health; + /* + * First clear out all interrupts. Then enable the one's that we + * can handle. + */ + rkt_writeb(dev, MUnit.OIMR, 0xff); + rkt_writel(dev, MUnit.ODR, 0xffffffff); + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); + if (aac_init_adapter(dev) == NULL) goto error_irq; /* @@ -438,6 +457,7 @@ error_kfree: kfree(dev->queues); error_irq: + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); free_irq(dev->scsi_host_ptr->irq, (void *)dev); error_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) } /** + * aac_rx_disable_interrupt - Disable interrupts + * @dev: Adapter + */ + +static void aac_rx_disable_interrupt(struct aac_dev *dev) +{ + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); +} + +/** * rx_sync_cmd - send a command and wait * @dev: Adapter * @command: Command to execute @@ -412,10 +422,19 @@ int aac_rx_init(struct aac_dev *dev) * Fill in the function dispatch table. */ dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; + dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; dev->a_ops.adapter_notify = aac_rx_notify_adapter; dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_check_health = aac_rx_check_health; + /* + * First clear out all interrupts. Then enable the one's that we + * can handle. + */ + rx_writeb(dev, MUnit.OIMR, 0xff); + rx_writel(dev, MUnit.ODR, 0xffffffff); + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); + if (aac_init_adapter(dev) == NULL) goto error_irq; /* @@ -438,6 +457,7 @@ error_kfree: kfree(dev->queues); error_irq: + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); free_irq(dev->scsi_host_ptr->irq, (void *)dev); error_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) } /** + * aac_sa_disable_interrupt - disable interrupt + * @dev: Which adapter to enable. + */ + +static void aac_sa_disable_interrupt (struct aac_dev *dev) +{ + sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); +} + +/** * aac_sa_notify_adapter - handle adapter notification * @dev: Adapter that notification is for * @event: Event to notidy @@ -214,9 +224,8 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command, static void aac_sa_interrupt_adapter (struct aac_dev *dev) { - u32 ret; sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, - &ret, NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); } /** @@ -352,10 +361,18 @@ int aac_sa_init(struct aac_dev *dev) */ dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter; + dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt; dev->a_ops.adapter_notify = aac_sa_notify_adapter; dev->a_ops.adapter_sync_cmd = sa_sync_cmd; dev->a_ops.adapter_check_health = aac_sa_check_health; + /* + * First clear out all interrupts. Then enable the one's that + * we can handle. + */ + sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); + sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | + DOORBELL_2 | DOORBELL_3 | DOORBELL_4)); if(aac_init_adapter(dev) == NULL) goto error_irq; @@ -381,6 +398,7 @@ error_kfree: kfree(dev->queues); error_irq: + sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff); free_irq(dev->scsi_host_ptr->irq, (void *)dev); error_iounmap: |