diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 98 |
1 files changed, 70 insertions, 28 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 73902d335767..0009818a4306 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -149,6 +149,45 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, | |||
149 | } | 149 | } |
150 | 150 | ||
151 | /** | 151 | /** |
152 | * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl | ||
153 | * @sdev: SCSI device to get identify data for | ||
154 | * @arg: User buffer area for identify data | ||
155 | * | ||
156 | * LOCKING: | ||
157 | * Defined by the SCSI layer. We don't really care. | ||
158 | * | ||
159 | * RETURNS: | ||
160 | * Zero on success, negative errno on error. | ||
161 | */ | ||
162 | static int ata_get_identity(struct scsi_device *sdev, void __user *arg) | ||
163 | { | ||
164 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
165 | struct ata_device *dev = ata_scsi_find_dev(ap, sdev); | ||
166 | u16 __user *dst = arg; | ||
167 | char buf[40]; | ||
168 | |||
169 | if (!dev) | ||
170 | return -ENOMSG; | ||
171 | |||
172 | if (copy_to_user(dst, dev->id, ATA_ID_WORDS * sizeof(u16))) | ||
173 | return -EFAULT; | ||
174 | |||
175 | ata_id_string(dev->id, buf, ATA_ID_PROD, ATA_ID_PROD_LEN); | ||
176 | if (copy_to_user(dst + ATA_ID_PROD, buf, ATA_ID_PROD_LEN)) | ||
177 | return -EFAULT; | ||
178 | |||
179 | ata_id_string(dev->id, buf, ATA_ID_FW_REV, ATA_ID_FW_REV_LEN); | ||
180 | if (copy_to_user(dst + ATA_ID_FW_REV, buf, ATA_ID_FW_REV_LEN)) | ||
181 | return -EFAULT; | ||
182 | |||
183 | ata_id_string(dev->id, buf, ATA_ID_SERNO, ATA_ID_SERNO_LEN); | ||
184 | if (copy_to_user(dst + ATA_ID_SERNO, buf, ATA_ID_SERNO_LEN)) | ||
185 | return -EFAULT; | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | /** | ||
152 | * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl | 191 | * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl |
153 | * @scsidev: Device to which we are issuing command | 192 | * @scsidev: Device to which we are issuing command |
154 | * @arg: User provided data for issuing command | 193 | * @arg: User provided data for issuing command |
@@ -159,7 +198,6 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, | |||
159 | * RETURNS: | 198 | * RETURNS: |
160 | * Zero on success, negative errno on error. | 199 | * Zero on success, negative errno on error. |
161 | */ | 200 | */ |
162 | |||
163 | int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) | 201 | int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) |
164 | { | 202 | { |
165 | int rc = 0; | 203 | int rc = 0; |
@@ -359,6 +397,9 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) | |||
359 | return -EINVAL; | 397 | return -EINVAL; |
360 | return 0; | 398 | return 0; |
361 | 399 | ||
400 | case HDIO_GET_IDENTITY: | ||
401 | return ata_get_identity(scsidev, arg); | ||
402 | |||
362 | case HDIO_DRIVE_CMD: | 403 | case HDIO_DRIVE_CMD: |
363 | if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) | 404 | if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) |
364 | return -EACCES; | 405 | return -EACCES; |
@@ -397,9 +438,9 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg) | |||
397 | * RETURNS: | 438 | * RETURNS: |
398 | * Command allocated, or %NULL if none available. | 439 | * Command allocated, or %NULL if none available. |
399 | */ | 440 | */ |
400 | struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, | 441 | static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, |
401 | struct scsi_cmnd *cmd, | 442 | struct scsi_cmnd *cmd, |
402 | void (*done)(struct scsi_cmnd *)) | 443 | void (*done)(struct scsi_cmnd *)) |
403 | { | 444 | { |
404 | struct ata_queued_cmd *qc; | 445 | struct ata_queued_cmd *qc; |
405 | 446 | ||
@@ -435,7 +476,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, | |||
435 | * LOCKING: | 476 | * LOCKING: |
436 | * inherited from caller | 477 | * inherited from caller |
437 | */ | 478 | */ |
438 | void ata_dump_status(unsigned id, struct ata_taskfile *tf) | 479 | static void ata_dump_status(unsigned id, struct ata_taskfile *tf) |
439 | { | 480 | { |
440 | u8 stat = tf->command, err = tf->feature; | 481 | u8 stat = tf->command, err = tf->feature; |
441 | 482 | ||
@@ -610,8 +651,8 @@ int ata_scsi_device_resume(struct scsi_device *sdev) | |||
610 | * LOCKING: | 651 | * LOCKING: |
611 | * spin_lock_irqsave(host lock) | 652 | * spin_lock_irqsave(host lock) |
612 | */ | 653 | */ |
613 | void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, | 654 | static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, |
614 | u8 *ascq, int verbose) | 655 | u8 *asc, u8 *ascq, int verbose) |
615 | { | 656 | { |
616 | int i; | 657 | int i; |
617 | 658 | ||
@@ -1359,7 +1400,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) | |||
1359 | goto nothing_to_do; | 1400 | goto nothing_to_do; |
1360 | 1401 | ||
1361 | qc->flags |= ATA_QCFLAG_IO; | 1402 | qc->flags |= ATA_QCFLAG_IO; |
1362 | qc->nsect = n_block; | 1403 | qc->nbytes = n_block * ATA_SECT_SIZE; |
1363 | 1404 | ||
1364 | rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags, | 1405 | rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags, |
1365 | qc->tag); | 1406 | qc->tag); |
@@ -1698,8 +1739,8 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, | |||
1698 | 1739 | ||
1699 | if (buflen > 35) { | 1740 | if (buflen > 35) { |
1700 | memcpy(&rbuf[8], "ATA ", 8); | 1741 | memcpy(&rbuf[8], "ATA ", 8); |
1701 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16); | 1742 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); |
1702 | ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4); | 1743 | ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4); |
1703 | if (rbuf[32] == 0 || rbuf[32] == ' ') | 1744 | if (rbuf[32] == 0 || rbuf[32] == ' ') |
1704 | memcpy(&rbuf[32], "n/a ", 4); | 1745 | memcpy(&rbuf[32], "n/a ", 4); |
1705 | } | 1746 | } |
@@ -1768,13 +1809,13 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf, | |||
1768 | 0, | 1809 | 0, |
1769 | 0x80, /* this page code */ | 1810 | 0x80, /* this page code */ |
1770 | 0, | 1811 | 0, |
1771 | ATA_SERNO_LEN, /* page len */ | 1812 | ATA_ID_SERNO_LEN, /* page len */ |
1772 | }; | 1813 | }; |
1773 | memcpy(rbuf, hdr, sizeof(hdr)); | 1814 | memcpy(rbuf, hdr, sizeof(hdr)); |
1774 | 1815 | ||
1775 | if (buflen > (ATA_SERNO_LEN + 4 - 1)) | 1816 | if (buflen > (ATA_ID_SERNO_LEN + 4 - 1)) |
1776 | ata_id_string(args->id, (unsigned char *) &rbuf[4], | 1817 | ata_id_string(args->id, (unsigned char *) &rbuf[4], |
1777 | ATA_ID_SERNO_OFS, ATA_SERNO_LEN); | 1818 | ATA_ID_SERNO, ATA_ID_SERNO_LEN); |
1778 | 1819 | ||
1779 | return 0; | 1820 | return 0; |
1780 | } | 1821 | } |
@@ -1799,19 +1840,18 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, | |||
1799 | { | 1840 | { |
1800 | int num; | 1841 | int num; |
1801 | const int sat_model_serial_desc_len = 68; | 1842 | const int sat_model_serial_desc_len = 68; |
1802 | const int ata_model_byte_len = 40; | ||
1803 | 1843 | ||
1804 | rbuf[1] = 0x83; /* this page code */ | 1844 | rbuf[1] = 0x83; /* this page code */ |
1805 | num = 4; | 1845 | num = 4; |
1806 | 1846 | ||
1807 | if (buflen > (ATA_SERNO_LEN + num + 3)) { | 1847 | if (buflen > (ATA_ID_SERNO_LEN + num + 3)) { |
1808 | /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */ | 1848 | /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */ |
1809 | rbuf[num + 0] = 2; | 1849 | rbuf[num + 0] = 2; |
1810 | rbuf[num + 3] = ATA_SERNO_LEN; | 1850 | rbuf[num + 3] = ATA_ID_SERNO_LEN; |
1811 | num += 4; | 1851 | num += 4; |
1812 | ata_id_string(args->id, (unsigned char *) rbuf + num, | 1852 | ata_id_string(args->id, (unsigned char *) rbuf + num, |
1813 | ATA_ID_SERNO_OFS, ATA_SERNO_LEN); | 1853 | ATA_ID_SERNO, ATA_ID_SERNO_LEN); |
1814 | num += ATA_SERNO_LEN; | 1854 | num += ATA_ID_SERNO_LEN; |
1815 | } | 1855 | } |
1816 | if (buflen > (sat_model_serial_desc_len + num + 3)) { | 1856 | if (buflen > (sat_model_serial_desc_len + num + 3)) { |
1817 | /* SAT defined lu model and serial numbers descriptor */ | 1857 | /* SAT defined lu model and serial numbers descriptor */ |
@@ -1823,11 +1863,11 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, | |||
1823 | memcpy(rbuf + num, "ATA ", 8); | 1863 | memcpy(rbuf + num, "ATA ", 8); |
1824 | num += 8; | 1864 | num += 8; |
1825 | ata_id_string(args->id, (unsigned char *) rbuf + num, | 1865 | ata_id_string(args->id, (unsigned char *) rbuf + num, |
1826 | ATA_ID_PROD_OFS, ata_model_byte_len); | 1866 | ATA_ID_PROD, ATA_ID_PROD_LEN); |
1827 | num += ata_model_byte_len; | 1867 | num += ATA_ID_PROD_LEN; |
1828 | ata_id_string(args->id, (unsigned char *) rbuf + num, | 1868 | ata_id_string(args->id, (unsigned char *) rbuf + num, |
1829 | ATA_ID_SERNO_OFS, ATA_SERNO_LEN); | 1869 | ATA_ID_SERNO, ATA_ID_SERNO_LEN); |
1830 | num += ATA_SERNO_LEN; | 1870 | num += ATA_ID_SERNO_LEN; |
1831 | } | 1871 | } |
1832 | rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */ | 1872 | rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */ |
1833 | return 0; | 1873 | return 0; |
@@ -1955,15 +1995,15 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last) | |||
1955 | */ | 1995 | */ |
1956 | static int ata_dev_supports_fua(u16 *id) | 1996 | static int ata_dev_supports_fua(u16 *id) |
1957 | { | 1997 | { |
1958 | unsigned char model[41], fw[9]; | 1998 | unsigned char model[ATA_ID_PROD_LEN + 1], fw[ATA_ID_FW_REV_LEN + 1]; |
1959 | 1999 | ||
1960 | if (!libata_fua) | 2000 | if (!libata_fua) |
1961 | return 0; | 2001 | return 0; |
1962 | if (!ata_id_has_fua(id)) | 2002 | if (!ata_id_has_fua(id)) |
1963 | return 0; | 2003 | return 0; |
1964 | 2004 | ||
1965 | ata_id_c_string(id, model, ATA_ID_PROD_OFS, sizeof(model)); | 2005 | ata_id_c_string(id, model, ATA_ID_PROD, sizeof(model)); |
1966 | ata_id_c_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw)); | 2006 | ata_id_c_string(id, fw, ATA_ID_FW_REV, sizeof(fw)); |
1967 | 2007 | ||
1968 | if (strcmp(model, "Maxtor")) | 2008 | if (strcmp(model, "Maxtor")) |
1969 | return 1; | 2009 | return 1; |
@@ -2661,7 +2701,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) | |||
2661 | * TODO: find out if we need to do more here to | 2701 | * TODO: find out if we need to do more here to |
2662 | * cover scatter/gather case. | 2702 | * cover scatter/gather case. |
2663 | */ | 2703 | */ |
2664 | qc->nsect = scmd->request_bufflen / ATA_SECT_SIZE; | 2704 | qc->nbytes = scmd->request_bufflen; |
2665 | 2705 | ||
2666 | /* request result TF */ | 2706 | /* request result TF */ |
2667 | qc->flags |= ATA_QCFLAG_RESULT_TF; | 2707 | qc->flags |= ATA_QCFLAG_RESULT_TF; |
@@ -3059,7 +3099,8 @@ void ata_scsi_hotplug(struct work_struct *work) | |||
3059 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 3099 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
3060 | struct ata_device *dev = &ap->device[i]; | 3100 | struct ata_device *dev = &ap->device[i]; |
3061 | if (ata_dev_enabled(dev) && !dev->sdev) { | 3101 | if (ata_dev_enabled(dev) && !dev->sdev) { |
3062 | queue_delayed_work(ata_aux_wq, &ap->hotplug_task, HZ); | 3102 | queue_delayed_work(ata_aux_wq, &ap->hotplug_task, |
3103 | round_jiffies_relative(HZ)); | ||
3063 | break; | 3104 | break; |
3064 | } | 3105 | } |
3065 | } | 3106 | } |
@@ -3264,7 +3305,8 @@ EXPORT_SYMBOL_GPL(ata_sas_port_init); | |||
3264 | 3305 | ||
3265 | void ata_sas_port_destroy(struct ata_port *ap) | 3306 | void ata_sas_port_destroy(struct ata_port *ap) |
3266 | { | 3307 | { |
3267 | ap->ops->port_stop(ap); | 3308 | if (ap->ops->port_stop) |
3309 | ap->ops->port_stop(ap); | ||
3268 | kfree(ap); | 3310 | kfree(ap); |
3269 | } | 3311 | } |
3270 | EXPORT_SYMBOL_GPL(ata_sas_port_destroy); | 3312 | EXPORT_SYMBOL_GPL(ata_sas_port_destroy); |