aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r--drivers/ata/libata-scsi.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 6e15c5ddae6d..dd41b1a1b304 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -826,17 +826,56 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
826 sdev->max_device_blocked = 1; 826 sdev->max_device_blocked = 1;
827} 827}
828 828
829static void ata_scsi_dev_config(struct scsi_device *sdev, 829/**
830 struct ata_device *dev) 830 * atapi_drain_needed - Check whether data transfer may overflow
831 * @request: request to be checked
832 *
833 * ATAPI commands which transfer variable length data to host
834 * might overflow due to application error or hardare bug. This
835 * function checks whether overflow should be drained and ignored
836 * for @request.
837 *
838 * LOCKING:
839 * None.
840 *
841 * RETURNS:
842 * 1 if ; otherwise, 0.
843 */
844static int atapi_drain_needed(struct request *rq)
845{
846 if (likely(!blk_pc_request(rq)))
847 return 0;
848
849 if (!rq->data_len || (rq->cmd_flags & REQ_RW))
850 return 0;
851
852 return atapi_cmd_type(rq->cmd[0]) == ATAPI_MISC;
853}
854
855static int ata_scsi_dev_config(struct scsi_device *sdev,
856 struct ata_device *dev)
831{ 857{
832 /* configure max sectors */ 858 /* configure max sectors */
833 blk_queue_max_sectors(sdev->request_queue, dev->max_sectors); 859 blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
834 860
835 if (dev->class == ATA_DEV_ATAPI) 861 if (dev->class == ATA_DEV_ATAPI) {
862 struct request_queue *q = sdev->request_queue;
863 void *buf;
864
836 /* set the min alignment */ 865 /* set the min alignment */
837 blk_queue_update_dma_alignment(sdev->request_queue, 866 blk_queue_update_dma_alignment(sdev->request_queue,
838 ATA_DMA_PAD_SZ - 1); 867 ATA_DMA_PAD_SZ - 1);
839 else { 868
869 /* configure draining */
870 buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL);
871 if (!buf) {
872 ata_dev_printk(dev, KERN_ERR,
873 "drain buffer allocation failed\n");
874 return -ENOMEM;
875 }
876
877 blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
878 } else {
840 /* ATA devices must be sector aligned */ 879 /* ATA devices must be sector aligned */
841 blk_queue_update_dma_alignment(sdev->request_queue, 880 blk_queue_update_dma_alignment(sdev->request_queue,
842 ATA_SECT_SIZE - 1); 881 ATA_SECT_SIZE - 1);
@@ -853,6 +892,8 @@ static void ata_scsi_dev_config(struct scsi_device *sdev,
853 depth = min(ATA_MAX_QUEUE - 1, depth); 892 depth = min(ATA_MAX_QUEUE - 1, depth);
854 scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); 893 scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
855 } 894 }
895
896 return 0;
856} 897}
857 898
858/** 899/**
@@ -871,13 +912,14 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
871{ 912{
872 struct ata_port *ap = ata_shost_to_port(sdev->host); 913 struct ata_port *ap = ata_shost_to_port(sdev->host);
873 struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); 914 struct ata_device *dev = __ata_scsi_find_dev(ap, sdev);
915 int rc = 0;
874 916
875 ata_scsi_sdev_config(sdev); 917 ata_scsi_sdev_config(sdev);
876 918
877 if (dev) 919 if (dev)
878 ata_scsi_dev_config(sdev, dev); 920 rc = ata_scsi_dev_config(sdev, dev);
879 921
880 return 0; 922 return rc;
881} 923}
882 924
883/** 925/**
@@ -897,6 +939,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
897void ata_scsi_slave_destroy(struct scsi_device *sdev) 939void ata_scsi_slave_destroy(struct scsi_device *sdev)
898{ 940{
899 struct ata_port *ap = ata_shost_to_port(sdev->host); 941 struct ata_port *ap = ata_shost_to_port(sdev->host);
942 struct request_queue *q = sdev->request_queue;
900 unsigned long flags; 943 unsigned long flags;
901 struct ata_device *dev; 944 struct ata_device *dev;
902 945
@@ -912,6 +955,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
912 ata_port_schedule_eh(ap); 955 ata_port_schedule_eh(ap);
913 } 956 }
914 spin_unlock_irqrestore(ap->lock, flags); 957 spin_unlock_irqrestore(ap->lock, flags);
958
959 kfree(q->dma_drain_buffer);
960 q->dma_drain_buffer = NULL;
961 q->dma_drain_size = 0;
915} 962}
916 963
917/** 964/**