libata: implement setting _SDD
PATCH 2/2 libata: implement setting _SDD
1 implement ata_acpi_push_id(), which is used to set _SDD 2 invoke ata_acpi_push_id() in ata_dev_configure()
Signed-off-by Zhao Forrest <[email protected]>
---
drivers/scsi/libata-acpi.c | 97 ++++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/libata-core.c | 8 ++++ drivers/scsi/libata.h | 5 ++ 3 files changed, 110 insertions(+), 0 deletions(-)
a52b4e04c0b9467f0993ed4c367fcd575e6a936f
drivers/scsi/libata-acpi.c +97 -0
@@ -652,3 +652,100 @@ int ata_acpi_exec_tfs(struct ata_port *a }EXPORT_SYMBOL_GPL (ata_acpi_exec_tfs); +/** +* ata_acpi_push_id - send Identify data to a drive +* @ap: the ata_port for the drive +* @ix: drive index +* +* _SDD ACPI object: for SATA mode only. +* Must be after Identify (Packet) Device -- uses its data. +*/ +int ata_acpi_push_id (struct ata_port *ap,unsigned int ix) +{ +acpi_handle handle; +acpi_integer pcidevfn; +int err = -ENODEV ; +struct device *dev = ap->host_set->dev; +struct ata_device *atadev = &ap->device[ix]; +u32 dev_adr; +acpi_status status; +struct acpi_object_list input; +union acpi_object in_params[1 ]; + +if (noacpi) +return 0 ; + +if (!(ap->flags &ATA_FLAG_SATA )) { +printk (KERN_DEBUG "%s: skipping for PATA mode\n" , + __FUNCTION__); +return 0 ; + } + +if (ata_msg_probe (ap)) +printk (KERN_DEBUG +"%s: ap->id: %d, ix = %d, port#: %d, hard_port#: %d\n" , + __FUNCTION__, ap->id, ix, + ap->port_no, ap->hard_port_no); + +/* Don't continue if not a SATA device. */ +if (!ata_id_is_sata (atadev->id)) { +if (ata_msg_probe (ap)) +printk (KERN_DEBUG "%s: ata_id_is_sata is False\n" , + __FUNCTION__); + goto out; + } + +/* Don't continue if device has no _ADR method. +* _SDD is intended for known motherboard devices. */ + err =sata_get_dev_handle (dev, &handle, &pcidevfn); +if (err <0 ) { +if (ata_msg_probe (ap)) +printk (KERN_DEBUG +"%s: sata_get_dev_handle failed (%d\n" , + __FUNCTION__, err); + goto out; + } + +/* Get this drive's _ADR info. if not already known. */ +if (!atadev->obj_handle) { + dev_adr =SATA_ADR_RSVD ; + err =get_sata_adr (dev, handle, pcidevfn, ix, ap, atadev, + &dev_adr); +if (err <0 || dev_adr ==SATA_ADR_RSVD || + !atadev->obj_handle) { +if (ata_msg_probe (ap)) +printk (KERN_DEBUG "%s: get_sata_adr failed: " +"err=%d, dev_adr=%u, obj_handle=0x%p\n" , + __FUNCTION__, err, dev_adr, + atadev->obj_handle); + goto out; + } + } + +/* Give the drive Identify data to the drive via the _SDD method */ +/* _SDD: set up input parameters */ + input.count =1 ; + input.pointer = in_params; + in_params[0 ].type =ACPI_TYPE_BUFFER ; + in_params[0 ].buffer.length =sizeof (atadev->id); + in_params[0 ].buffer.pointer = (u8 *)atadev->id; +/* Output buffer: _SDD has no output */ + +/* It's OK for _SDD to be missing too. */ +swap_buf_le16 (atadev->id,ATA_ID_WORDS ); + status =acpi_evaluate_object (atadev->obj_handle,"_SDD" , &input,NULL ); +swap_buf_le16 (atadev->id,ATA_ID_WORDS ); + + err =ACPI_FAILURE (status) ? -EIO :0 ; +if (err <0 ) { +if (ata_msg_probe (ap)) +printk (KERN_DEBUG +"ata%u(%u): %s _SDD error: status = 0x%x\n" , + ap->id, ap->device->devno, + __FUNCTION__, status); + } +out: +return err; +} +EXPORT_SYMBOL_GPL (ata_acpi_push_id); +
drivers/scsi/libata-core.c +8 -0
@@ -1505,6 +1505,14 @@ int ata_dev_configure(struct ata_deviceif (ap->ops->dev_config) ap->ops->dev_config (ap, dev); +/* set _SDD */ + rc =ata_acpi_push_id (ap, dev->devno); +if (rc) { +ata_dev_printk (dev,KERN_WARNING ,"failed to set _SDD(%d)\n" , + rc); + goto err_out_nosup; + } +if (ata_msg_probe (ap))ata_dev_printk (dev,KERN_DEBUG ,"%s: EXIT, drv_stat = 0x%x\n" , __FUNCTION__,ata_chk_status (ap));
drivers/scsi/libata.h +5 -0
@@ -123,6 +123,7 @@ extern int do_drive_get_GTF(struct ata_pextern int do_drive_set_taskfiles (struct ata_port *ap,struct ata_device *atadev,unsigned int gtf_length,unsigned long gtf_address);extern int ata_acpi_exec_tfs (struct ata_port *ap); +extern int ata_acpi_push_id (struct ata_port *ap,unsigned int ix);#else static inline int do_drive_get_GTF(struct ata_port *ap, int ix, unsigned int *gtf_length, unsigned long *gtf_address,
@@ -140,6 +141,10 @@ static inline int ata_acpi_exec_tfs(stru {return 0 ; } +static inline int ata_acpi_push_id (struct ata_port *ap,unsigned int ix) +{ +return 0 ; +}#endif #endif /* __LIBATA_H__ */
Signature · 1 line
1.2.6
Quoted 6 lines · forrest
1 implement
ata_acpi_push_id(), which is used to set_SDD2 invokeata_acpi_push_id()inata_dev_configure()Signed-off-by Zhao Forrest <[email protected]>
Signed-off-by Randy Dunlap <[email protected]>
However, don't some of the printk's need to be updated to use the new printk macros with debugging levels?
Quoted 122 lines
---
drivers/scsi/libata-acpi.c | 97 ++++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/libata-core.c | 8 ++++ drivers/scsi/libata.h | 5 ++ 3 files changed, 110 insertions(+), 0 deletions(-)
a52b4e04c0b9467f0993ed4c367fcd575e6a936fdrivers/scsi/libata-acpi.c +97
-0@@ -652,3 +652,100 @@ int ata_acpi_exec_tfs(struct ata_port *a }EXPORT_SYMBOL_GPL (ata_acpi_exec_tfs); +/** +* ata_acpi_push_id - send Identify data to a drive +* @ap: the ata_port for the drive +* @ix: drive index +* +* _SDD ACPI object: for SATA mode only. +* Must be after Identify (Packet) Device -- uses its data. +*/ +int ata_acpi_push_id (struct ata_port *ap,unsigned int ix) +{ +acpi_handle handle; +acpi_integer pcidevfn; +int err = -ENODEV ; +struct device *dev = ap->host_set->dev; +struct ata_device *atadev = &ap->device[ix]; +u32 dev_adr; +acpi_status status; +struct acpi_object_list input; +union acpi_object in_params[1 ]; + +if (noacpi) +return 0 ; + +if (!(ap->flags &ATA_FLAG_SATA )) { +printk (KERN_DEBUG "%s: skipping for PATA mode\n" , + __FUNCTION__); +return 0 ; + } + +if (ata_msg_probe (ap)) +printk (KERN_DEBUG +"%s: ap->id: %d, ix = %d, port#: %d, hard_port#: %d\n" , + __FUNCTION__, ap->id, ix, + ap->port_no, ap->hard_port_no); + +/* Don't continue if not a SATA device. */ +if (!ata_id_is_sata (atadev->id)) { +if (ata_msg_probe (ap)) +printk (KERN_DEBUG "%s: ata_id_is_sata is False\n" , + __FUNCTION__); + goto out; + } + +/* Don't continue if device has no _ADR method. +* _SDD is intended for known motherboard devices. */ + err =sata_get_dev_handle (dev, &handle, &pcidevfn); +if (err <0 ) { +if (ata_msg_probe (ap)) +printk (KERN_DEBUG +"%s: sata_get_dev_handle failed (%d\n" , + __FUNCTION__, err); + goto out; + } + +/* Get this drive's _ADR info. if not already known. */ +if (!atadev->obj_handle) { + dev_adr =SATA_ADR_RSVD ; + err =get_sata_adr (dev, handle, pcidevfn, ix, ap, atadev, + &dev_adr); +if (err <0 || dev_adr ==SATA_ADR_RSVD || + !atadev->obj_handle) { +if (ata_msg_probe (ap)) +printk (KERN_DEBUG "%s: get_sata_adr failed: " +"err=%d, dev_adr=%u, obj_handle=0x%p\n" , + __FUNCTION__, err, dev_adr, + atadev->obj_handle); + goto out; + } + } + +/* Give the drive Identify data to the drive via the _SDD method */ +/* _SDD: set up input parameters */ + input.count =1 ; + input.pointer = in_params; + in_params[0 ].type =ACPI_TYPE_BUFFER ; + in_params[0 ].buffer.length =sizeof (atadev->id); + in_params[0 ].buffer.pointer = (u8 *)atadev->id; +/* Output buffer: _SDD has no output */ + +/* It's OK for _SDD to be missing too. */ +swap_buf_le16 (atadev->id,ATA_ID_WORDS ); + status =acpi_evaluate_object (atadev->obj_handle,"_SDD" , &input,NULL ); +swap_buf_le16 (atadev->id,ATA_ID_WORDS ); + + err =ACPI_FAILURE (status) ? -EIO :0 ; +if (err <0 ) { +if (ata_msg_probe (ap)) +printk (KERN_DEBUG +"ata%u(%u): %s _SDD error: status = 0x%x\n" , + ap->id, ap->device->devno, + __FUNCTION__, status); + } +out: +return err; +} +EXPORT_SYMBOL_GPL (ata_acpi_push_id); +drivers/scsi/libata-core.c +1
-0@@ -1505,6 +1505,14 @@ int ata_dev_configure(struct ata_deviceif (ap->ops->dev_config) ap->ops->dev_config (ap, dev); +/* set _SDD */
drivers/scsi/libata-core.c int ata_dev_configure(struct ata_device · line 1518
Quoted 10 lines
drivers/scsi/libata-core.c +7
-0+ rc =ata_acpi_push_id (ap, dev->devno); +if (rc) { +ata_dev_printk (dev,KERN_WARNING ,"failed to set _SDD(%d)\n" , + rc); + goto err_out_nosup; + } +if (ata_msg_probe (ap))ata_dev_printk (dev,KERN_DEBUG ,"%s: EXIT, drv_stat = 0x%x\n" , __FUNCTION__,ata_chk_status (ap));
---
~Randy
Quoted 5 lines · forrest
1 implement
ata_acpi_push_id(), which is used to set_SDD2 invokeata_acpi_push_id()inata_dev_configure()Signed-off-by Zhao Forrest <[email protected]>
seems OK except for all the messaging -- same comments as with patch #1