ata: fix read_id() ata port operation interface
authorDamien Le Moal <damien.lemoal@opensource.wdc.com>
Tue, 4 Jan 2022 08:54:18 +0000 (17:54 +0900)
committerDamien Le Moal <damien.lemoal@opensource.wdc.com>
Fri, 14 Jan 2022 06:17:16 +0000 (15:17 +0900)
Drivers that need to tweak a device IDENTIFY data implement the
read_id() port operation. The IDENTIFY data buffer is passed as an
argument to the read_id() operation for drivers to use. However, when
this operation is called, the IDENTIFY data is not yet converted to CPU
endian and contains le16 words.

Change the interface of the read_id operation to pass a __le16 * pointer
to the IDENTIFY data buffer to clarify the buffer endianness. Fix the
pata_netcell, pata_it821x, ahci_xgene, ahci_ceva and ahci_brcm drivers
implementation of this operation and modify the code to corretly deal
with identify data words manipulation to avoid sparse warnings such as:

drivers/ata/ahci_xgene.c:262:33: warning: invalid assignment: &=
drivers/ata/ahci_xgene.c:262:33:    left side has type unsigned short
drivers/ata/ahci_xgene.c:262:33:    right side has type restricted __le16

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
drivers/ata/ahci_brcm.c
drivers/ata/ahci_ceva.c
drivers/ata/ahci_xgene.c
drivers/ata/libata-core.c
drivers/ata/pata_it821x.c
drivers/ata/pata_netcell.c
include/linux/libata.h

index 6e9c5ade4c2eaeae5933a4b7f60c722020151842..ba695338927ad42969b930f72463564890a95ed8 100644 (file)
@@ -246,7 +246,7 @@ static void brcm_sata_init(struct brcm_ahci_priv *priv)
 }
 
 static unsigned int brcm_ahci_read_id(struct ata_device *dev,
-                                     struct ata_taskfile *tf, u16 *id)
+                                     struct ata_taskfile *tf, __le16 *id)
 {
        struct ata_port *ap = dev->link->ap;
        struct ata_host *host = ap->host;
index e9c7c07fd84c8f063d317aadd54e321afac327d3..acf59f51b3569d71c755d66856f2452c28f7d52d 100644 (file)
@@ -92,9 +92,8 @@ struct ceva_ahci_priv {
 };
 
 static unsigned int ceva_ahci_read_id(struct ata_device *dev,
-                                       struct ata_taskfile *tf, u16 *id)
+                                     struct ata_taskfile *tf, __le16 *id)
 {
-       __le16 *__id = (__le16 *)id;
        u32 err_mask;
 
        err_mask = ata_do_dev_read_id(dev, tf, id);
@@ -104,7 +103,7 @@ static unsigned int ceva_ahci_read_id(struct ata_device *dev,
         * Since CEVA controller does not support device sleep feature, we
         * need to clear DEVSLP (bit 8) in word78 of the IDENTIFY DEVICE data.
         */
-       __id[ATA_ID_FEATURE_SUPP] &= cpu_to_le16(~(1 << 8));
+       id[ATA_ID_FEATURE_SUPP] &= cpu_to_le16(~(1 << 8));
 
        return 0;
 }
index 68ec7e9430b28e8622044e6e106f1bf5a5ad4e5c..8e206379d699f080762962302cec70dbc3d0eca7 100644 (file)
@@ -237,7 +237,7 @@ static bool xgene_ahci_is_memram_inited(struct xgene_ahci_context *ctx)
  * does not support DEVSLP.
  */
 static unsigned int xgene_ahci_read_id(struct ata_device *dev,
-                                      struct ata_taskfile *tf, u16 *id)
+                                      struct ata_taskfile *tf, __le16 *id)
 {
        u32 err_mask;
 
index 9c2947905d1eb4ce1b1721bf74eb2b9ef658ce8a..67f88027680acefe4e2eed3c1b598773625d644a 100644 (file)
@@ -1722,7 +1722,7 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
  *     this function is wrapped or replaced by the driver
  */
 unsigned int ata_do_dev_read_id(struct ata_device *dev,
-                                       struct ata_taskfile *tf, u16 *id)
+                               struct ata_taskfile *tf, __le16 *id)
 {
        return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE,
                                     id, sizeof(id[0]) * ATA_ID_WORDS, 0);
@@ -1795,9 +1795,9 @@ retry:
        tf.flags |= ATA_TFLAG_POLLING;
 
        if (ap->ops->read_id)
-               err_mask = ap->ops->read_id(dev, &tf, id);
+               err_mask = ap->ops->read_id(dev, &tf, (__le16 *)id);
        else
-               err_mask = ata_do_dev_read_id(dev, &tf, id);
+               err_mask = ata_do_dev_read_id(dev, &tf, (__le16 *)id);
 
        if (err_mask) {
                if (err_mask & AC_ERR_NODEV_HINT) {
index b77ef0046dbec9d5087a424d3c561c0d6eda0136..8a5b4e0079abf5ea734af40afecc5d1cde1c3557 100644 (file)
@@ -537,7 +537,7 @@ static void it821x_dev_config(struct ata_device *adev)
  */
 
 static unsigned int it821x_read_id(struct ata_device *adev,
-                                       struct ata_taskfile *tf, u16 *id)
+                                  struct ata_taskfile *tf, __le16 *id)
 {
        unsigned int err_mask;
        unsigned char model_num[ATA_ID_PROD_LEN + 1];
@@ -545,21 +545,20 @@ static unsigned int it821x_read_id(struct ata_device *adev,
        err_mask = ata_do_dev_read_id(adev, tf, id);
        if (err_mask)
                return err_mask;
-       ata_id_c_string(id, model_num, ATA_ID_PROD, sizeof(model_num));
+       ata_id_c_string((u16 *)id, model_num, ATA_ID_PROD, sizeof(model_num));
 
-       id[83] &= ~(1 << 12);   /* Cache flush is firmware handled */
-       id[83] &= ~(1 << 13);   /* Ditto for LBA48 flushes */
-       id[84] &= ~(1 << 6);    /* No FUA */
-       id[85] &= ~(1 << 10);   /* No HPA */
-       id[76] = 0;             /* No NCQ/AN etc */
+       id[83] &= cpu_to_le16(~(1 << 12)); /* Cache flush is firmware handled */
+       id[84] &= cpu_to_le16(~(1 << 6));  /* No FUA */
+       id[85] &= cpu_to_le16(~(1 << 10)); /* No HPA */
+       id[76] = 0;                        /* No NCQ/AN etc */
 
        if (strstr(model_num, "Integrated Technology Express")) {
                /* Set feature bits the firmware neglects */
-               id[49] |= 0x0300;       /* LBA, DMA */
-               id[83] &= 0x7FFF;
-               id[83] |= 0x4400;       /* Word 83 is valid and LBA48 */
-               id[86] |= 0x0400;       /* LBA48 on */
-               id[ATA_ID_MAJOR_VER] |= 0x1F;
+               id[49] |= cpu_to_le16(0x0300);  /* LBA, DMA */
+               id[83] &= cpu_to_le16(0x7FFF);
+               id[83] |= cpu_to_le16(0x4400);  /* Word 83 is valid and LBA48 */
+               id[86] |= cpu_to_le16(0x0400);  /* LBA48 on */
+               id[ATA_ID_MAJOR_VER] |= cpu_to_le16(0x1F);
                /* Clear the serial number because it's different each boot
                   which breaks validation on resume */
                memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN);
index a7ecc1a204b5a5db7203f43a296f3cfa10d333af..06929e77c4915eb0c35d575467bc49cc5db04ec1 100644 (file)
 /* No PIO or DMA methods needed for this device */
 
 static unsigned int netcell_read_id(struct ata_device *adev,
-                                       struct ata_taskfile *tf, u16 *id)
+                                   struct ata_taskfile *tf, __le16 *id)
 {
        unsigned int err_mask = ata_do_dev_read_id(adev, tf, id);
+
        /* Firmware forgets to mark words 85-87 valid */
        if (err_mask == 0)
-               id[ATA_ID_CSF_DEFAULT] |= 0x4000;
+               id[ATA_ID_CSF_DEFAULT] |= cpu_to_le16(0x4000);
        return err_mask;
 }
 
index 2e5e7c40c991a8a0741b9543ecde2344597cc635..bf706cd4567441d8c92293b8f99079fcc3b12f7c 100644 (file)
@@ -884,7 +884,8 @@ struct ata_port_operations {
        void (*set_piomode)(struct ata_port *ap, struct ata_device *dev);
        void (*set_dmamode)(struct ata_port *ap, struct ata_device *dev);
        int  (*set_mode)(struct ata_link *link, struct ata_device **r_failed_dev);
-       unsigned int (*read_id)(struct ata_device *dev, struct ata_taskfile *tf, u16 *id);
+       unsigned int (*read_id)(struct ata_device *dev, struct ata_taskfile *tf,
+                               __le16 *id);
 
        void (*dev_config)(struct ata_device *dev);
 
@@ -1119,7 +1120,7 @@ extern void ata_id_string(const u16 *id, unsigned char *s,
 extern void ata_id_c_string(const u16 *id, unsigned char *s,
                            unsigned int ofs, unsigned int len);
 extern unsigned int ata_do_dev_read_id(struct ata_device *dev,
-                                       struct ata_taskfile *tf, u16 *id);
+                                      struct ata_taskfile *tf, __le16 *id);
 extern void ata_qc_complete(struct ata_queued_cmd *qc);
 extern u64 ata_qc_get_active(struct ata_port *ap);
 extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd);