|
@@ -148,6 +148,45 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
|
|
|
|
+ * @sdev: SCSI device to get identify data for
|
|
|
|
+ * @arg: User buffer area for identify data
|
|
|
|
+ *
|
|
|
|
+ * LOCKING:
|
|
|
|
+ * Defined by the SCSI layer. We don't really care.
|
|
|
|
+ *
|
|
|
|
+ * RETURNS:
|
|
|
|
+ * Zero on success, negative errno on error.
|
|
|
|
+ */
|
|
|
|
+static int ata_get_identity(struct scsi_device *sdev, void __user *arg)
|
|
|
|
+{
|
|
|
|
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
|
|
|
|
+ struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
|
|
|
|
+ u16 __user *dst = arg;
|
|
|
|
+ char buf[40];
|
|
|
|
+
|
|
|
|
+ if (!dev)
|
|
|
|
+ return -ENOMSG;
|
|
|
|
+
|
|
|
|
+ if (copy_to_user(dst, dev->id, ATA_ID_WORDS * sizeof(u16)))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ ata_id_string(dev->id, buf, ATA_ID_PROD, ATA_ID_PROD_LEN);
|
|
|
|
+ if (copy_to_user(dst + ATA_ID_PROD, buf, ATA_ID_PROD_LEN))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ ata_id_string(dev->id, buf, ATA_ID_FW_REV, ATA_ID_FW_REV_LEN);
|
|
|
|
+ if (copy_to_user(dst + ATA_ID_FW_REV, buf, ATA_ID_FW_REV_LEN))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ ata_id_string(dev->id, buf, ATA_ID_SERNO, ATA_ID_SERNO_LEN);
|
|
|
|
+ if (copy_to_user(dst + ATA_ID_SERNO, buf, ATA_ID_SERNO_LEN))
|
|
|
|
+ return -EFAULT;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
|
|
* ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
|
|
* @scsidev: Device to which we are issuing command
|
|
* @scsidev: Device to which we are issuing command
|
|
@@ -159,7 +198,6 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
|
|
* RETURNS:
|
|
* RETURNS:
|
|
* Zero on success, negative errno on error.
|
|
* Zero on success, negative errno on error.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|
int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
|
{
|
|
{
|
|
int rc = 0;
|
|
int rc = 0;
|
|
@@ -359,6 +397,9 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
+ case HDIO_GET_IDENTITY:
|
|
|
|
+ return ata_get_identity(scsidev, arg);
|
|
|
|
+
|
|
case HDIO_DRIVE_CMD:
|
|
case HDIO_DRIVE_CMD:
|
|
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
|
|
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
|
|
return -EACCES;
|
|
return -EACCES;
|