Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-mmc
[pandora-kernel.git] / drivers / scsi / dc395x.c
index 0c56095..ff2b179 100644 (file)
@@ -3347,21 +3347,14 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
 {
        u8 tempcnt, status;
        struct scsi_cmnd *cmd = srb->cmd;
-       struct ScsiInqData *ptr;
        enum dma_data_direction dir = cmd->sc_data_direction;
-
-       if (cmd->use_sg) {
-               struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
-               ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
-       } else {
-               ptr = (struct ScsiInqData *)(cmd->request_buffer);
-       }
+       int ckc_only = 1;
 
        dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid,
                srb->cmd->device->id, srb->cmd->device->lun);
-       dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p addr=%p\n",
+       dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n",
                srb, cmd->use_sg, srb->sg_index, srb->sg_count,
-               cmd->request_buffer, ptr);
+               cmd->request_buffer);
        status = srb->target_status;
        if (srb->flag & AUTO_REQSENSE) {
                dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n");
@@ -3500,29 +3493,47 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
                                            srb->segment_x[0].address,
                                            cmd->request_bufflen, dir);
        }
-
-       if ((cmd->result & RES_DID) == 0 && cmd->cmnd[0] == INQUIRY
-           && cmd->cmnd[2] == 0 && cmd->request_bufflen >= 8
-           && dir != PCI_DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2)
-               dcb->inquiry7 = ptr->Flags;
+       ckc_only = 0;
 /* Check Error Conditions */
       ckc_e:
 
+       if (cmd->cmnd[0] == INQUIRY) {
+               unsigned char *base = NULL;
+               struct ScsiInqData *ptr;
+               unsigned long flags = 0;
+
+               if (cmd->use_sg) {
+                       struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
+                       size_t offset = 0, len = sizeof(struct ScsiInqData);
+
+                       local_irq_save(flags);
+                       base = scsi_kmap_atomic_sg(sg, cmd->use_sg, &offset, &len);
+                       ptr = (struct ScsiInqData *)(base + offset);
+               } else
+                       ptr = (struct ScsiInqData *)(cmd->request_buffer);
+
+               if (!ckc_only && (cmd->result & RES_DID) == 0
+                   && cmd->cmnd[2] == 0 && cmd->request_bufflen >= 8
+                   && dir != PCI_DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2)
+                       dcb->inquiry7 = ptr->Flags;
+
        /*if( srb->cmd->cmnd[0] == INQUIRY && */
        /*  (host_byte(cmd->result) == DID_OK || status_byte(cmd->result) & CHECK_CONDITION) ) */
-       if (cmd->cmnd[0] == INQUIRY && (cmd->result == (DID_OK << 16)
-                                        || status_byte(cmd->
-                                                       result) &
-                                        CHECK_CONDITION)) {
-
-               if (!dcb->init_tcq_flag) {
-                       add_dev(acb, dcb, ptr);
-                       dcb->init_tcq_flag = 1;
+               if ((cmd->result == (DID_OK << 16)
+                    || status_byte(cmd->result) &
+                    CHECK_CONDITION)) {
+                       if (!dcb->init_tcq_flag) {
+                               add_dev(acb, dcb, ptr);
+                               dcb->init_tcq_flag = 1;
+                       }
                }
 
+               if (cmd->use_sg) {
+                       scsi_kunmap_atomic_sg(base);
+                       local_irq_restore(flags);
+               }
        }
 
-
        /* Here is the info for Doug Gilbert's sg3 ... */
        cmd->resid = srb->total_xfer_length;
        /* This may be interpreted by sb. or not ... */
@@ -3760,7 +3771,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
  * @target: The target for the new device.
  * @lun: The lun for the new device.
  *
- * Return the new device if succesfull or NULL on failure.
+ * Return the new device if successful or NULL on failure.
  **/
 static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb,
                u8 target, u8 lun)
@@ -4551,7 +4562,7 @@ static int __devinit adapter_init(struct AdapterCtlBlk *acb,
        acb->io_port_base = io_port;
        acb->io_port_len = io_port_len;
        
-       if (request_irq(irq, dc395x_interrupt, SA_SHIRQ, DC395X_NAME, acb)) {
+       if (request_irq(irq, dc395x_interrupt, IRQF_SHARED, DC395X_NAME, acb)) {
                /* release the region we just claimed */
                dprintkl(KERN_INFO, "Failed to register IRQ\n");
                goto failed;