UPSTREAM: drm: bridge/dw_hdmi: add atomic API support
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / 3w-xxxx.c
index 56662ae03dea65adad90665acc1e55690a192fea..2940bd769936cd7f75d2d20adc324914b0df4b84 100644 (file)
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_eh.h>
 #include "3w-xxxx.h"
 
 /* Globals */
@@ -522,19 +523,6 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
        return len;
 } /* End tw_show_stats() */
 
-/* This function will set a devices queue depth */
-static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth,
-                                int reason)
-{
-       if (reason != SCSI_QDEPTH_DEFAULT)
-               return -EOPNOTSUPP;
-
-       if (queue_depth > TW_Q_LENGTH-2)
-               queue_depth = TW_Q_LENGTH-2;
-       scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
-       return queue_depth;
-} /* End tw_change_queue_depth() */
-
 /* Create sysfs 'stats' entry */
 static struct device_attribute tw_host_stats_attr = {
        .attr = {
@@ -1283,32 +1271,6 @@ static int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
        return 0;
 } /* End tw_initialize_device_extension() */
 
-static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
-{
-       int use_sg;
-
-       dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
-
-       use_sg = scsi_dma_map(cmd);
-       if (use_sg < 0) {
-               printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
-               return 0;
-       }
-
-       cmd->SCp.phase = TW_PHASE_SGLIST;
-       cmd->SCp.have_data_in = use_sg;
-
-       return use_sg;
-} /* End tw_map_scsi_sg_data() */
-
-static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
-{
-       dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
-
-       if (cmd->SCp.phase == TW_PHASE_SGLIST)
-               scsi_dma_unmap(cmd);
-} /* End tw_unmap_scsi_data() */
-
 /* This function will reset a device extension */
 static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
 {
@@ -1331,8 +1293,8 @@ static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
                        srb = tw_dev->srb[i];
                        if (srb != NULL) {
                                srb->result = (DID_RESET << 16);
-                               tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
-                               tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
+                               scsi_dma_unmap(srb);
+                               srb->scsi_done(srb);
                        }
                }
        }
@@ -1779,8 +1741,8 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
        command_packet->byte8.io.lba = lba;
        command_packet->byte6.block_count = num_sectors;
 
-       use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
-       if (!use_sg)
+       use_sg = scsi_dma_map(srb);
+       if (use_sg <= 0)
                return 1;
 
        scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) {
@@ -1967,9 +1929,6 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c
        /* Save the scsi command for use by the ISR */
        tw_dev->srb[request_id] = SCpnt;
 
-       /* Initialize phase to zero */
-       SCpnt->SCp.phase = TW_PHASE_INITIAL;
-
        switch (*command) {
                case READ_10:
                case READ_6:
@@ -2009,7 +1968,8 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c
                        printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
                        tw_dev->state[request_id] = TW_S_COMPLETED;
                        tw_state_request_finish(tw_dev, request_id);
-                       SCpnt->result = (DID_BAD_TARGET << 16);
+                       SCpnt->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+                       scsi_build_sense_buffer(1, SCpnt->sense_buffer, ILLEGAL_REQUEST, 0x20, 0);
                        done(SCpnt);
                        retval = 0;
        }
@@ -2196,12 +2156,11 @@ static irqreturn_t tw_interrupt(int irq, void *dev_instance)
 
                                /* Now complete the io */
                                if ((error != TW_ISR_DONT_COMPLETE)) {
+                                       scsi_dma_unmap(tw_dev->srb[request_id]);
+                                       tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
                                        tw_dev->state[request_id] = TW_S_COMPLETED;
                                        tw_state_request_finish(tw_dev, request_id);
                                        tw_dev->posted_request_count--;
-                                       tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
-                                       
-                                       tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
                                }
                        }
                                
@@ -2268,7 +2227,7 @@ static struct scsi_host_template driver_template = {
        .queuecommand           = tw_scsi_queue,
        .eh_host_reset_handler  = tw_scsi_eh_reset,
        .bios_param             = tw_scsi_biosparam,
-       .change_queue_depth     = tw_change_queue_depth,
+       .change_queue_depth     = scsi_change_queue_depth,
        .can_queue              = TW_Q_LENGTH-2,
        .slave_configure        = tw_slave_configure,
        .this_id                = -1,
@@ -2277,7 +2236,8 @@ static struct scsi_host_template driver_template = {
        .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,  
        .use_clustering         = ENABLE_CLUSTERING,
        .shost_attrs            = tw_host_attrs,
-       .emulated               = 1
+       .emulated               = 1,
+       .no_write_same          = 1,
 };
 
 /* This function will probe and initialize a card */