[PATCH] libata: convert dev->id to pointer
authorTejun Heo <htejun@gmail.com>
Wed, 1 Mar 2006 07:09:35 +0000 (16:09 +0900)
committerJeff Garzik <jeff@garzik.org>
Fri, 3 Mar 2006 22:31:04 +0000 (17:31 -0500)
Convert dev->id from array to pointer.  This is to accomodate
revalidation.  During revalidation, both old and new IDENTIFY pages
should be accessible and single ->id array doesn't cut it.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/scsi/libata-core.c
include/linux/libata.h

index e34b421eb2a30cf94fb3d9eec25662c7bd5ebc76..fecda706d85f232bf7782cee297c243a2e1440bd 100644 (file)
@@ -911,7 +911,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
  *     @dev: target device
  *     @p_class: pointer to class of the target device (may be changed)
  *     @post_reset: is this read ID post-reset?
- *     @id: buffer to fill IDENTIFY page into
+ *     @p_id: read IDENTIFY page (newly allocated)
  *
  *     Read ID data from the specified device.  ATA_CMD_ID_ATA is
  *     performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
@@ -926,12 +926,13 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
  *     0 on success, -errno otherwise.
  */
 static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
-                          unsigned int *p_class, int post_reset, u16 *id)
+                          unsigned int *p_class, int post_reset, u16 **p_id)
 {
        unsigned int class = *p_class;
        unsigned int using_edd;
        struct ata_taskfile tf;
        unsigned int err_mask = 0;
+       u16 *id;
        const char *reason;
        int rc;
 
@@ -945,6 +946,13 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
 
        ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
 
+       id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
+       if (id == NULL) {
+               rc = -ENOMEM;
+               reason = "out of memory";
+               goto err_out;
+       }
+
  retry:
        ata_tf_init(ap, &tf, dev->devno);
 
@@ -1035,11 +1043,13 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
        }
 
        *p_class = class;
+       *p_id = id;
        return 0;
 
  err_out:
        printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n",
               ap->id, dev->devno, reason);
+       kfree(id);
        return rc;
 }
 
@@ -1079,7 +1089,8 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
 
        DPRINTK("ENTER, host %u, dev %u\n", ap->id, device);
 
-       rc = ata_dev_read_id(ap, dev, &dev->class, 1, dev->id);
+       WARN_ON(dev->id != NULL);
+       rc = ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id);
        if (rc)
                goto err_out;
 
@@ -4732,11 +4743,14 @@ void ata_host_set_remove(struct ata_host_set *host_set)
 int ata_scsi_release(struct Scsi_Host *host)
 {
        struct ata_port *ap = (struct ata_port *) &host->hostdata[0];
+       int i;
 
        DPRINTK("ENTER\n");
 
        ap->ops->port_disable(ap);
        ata_host_remove(ap, 0);
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               kfree(ap->device[i].id);
 
        DPRINTK("EXIT\n");
        return 1;
index 22e86cb2d1662cc0c040cc07e6df645ca1f40943..9f273dd1958cfced336de8aa1123f28736ca31ef 100644 (file)
@@ -339,7 +339,7 @@ struct ata_device {
        unsigned long           flags;          /* ATA_DFLAG_xxx */
        unsigned int            class;          /* ATA_DEV_xxx */
        unsigned int            devno;          /* 0 or 1 */
-       u16                     id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
+       u16                     *id;            /* IDENTIFY xxx DEVICE data */
        u8                      pio_mode;
        u8                      dma_mode;
        u8                      xfer_mode;
This page took 0.031001 seconds and 5 git commands to generate.