-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libata: identify and init ZPODD devices
The ODD can be enabled for ZPODD if the following three conditions are satisfied: 1 The ODD supports device attention; 2 The platform can runtime power off the ODD through ACPI; 3 The ODD is either slot type or drawer type. For such ODDs, zpodd_init is called and a new structure is allocated for it to store ZPODD related stuffs. And the zpodd_dev_enabled function is used to test if ZPODD is currently enabled for this ODD. A new config CONFIG_SATA_ZPODD is added to selectively build ZPODD code. Signed-off-by: Aaron Lu <aaron.lu@intel.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
- Loading branch information
Aaron Lu
authored and
Jeff Garzik
committed
Jan 21, 2013
1 parent
1757d90
commit afe7595
Showing
8 changed files
with
170 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#include <linux/libata.h> | ||
#include <linux/cdrom.h> | ||
|
||
#include "libata.h" | ||
|
||
enum odd_mech_type { | ||
ODD_MECH_TYPE_SLOT, | ||
ODD_MECH_TYPE_DRAWER, | ||
ODD_MECH_TYPE_UNSUPPORTED, | ||
}; | ||
|
||
struct zpodd { | ||
enum odd_mech_type mech_type; /* init during probe, RO afterwards */ | ||
struct ata_device *dev; | ||
}; | ||
|
||
/* Per the spec, only slot type and drawer type ODD can be supported */ | ||
static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) | ||
{ | ||
char buf[16]; | ||
unsigned int ret; | ||
struct rm_feature_desc *desc = (void *)(buf + 8); | ||
struct ata_taskfile tf = {}; | ||
|
||
char cdb[] = { GPCMD_GET_CONFIGURATION, | ||
2, /* only 1 feature descriptor requested */ | ||
0, 3, /* 3, removable medium feature */ | ||
0, 0, 0,/* reserved */ | ||
0, sizeof(buf), | ||
0, 0, 0, | ||
}; | ||
|
||
tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
tf.command = ATA_CMD_PACKET; | ||
tf.protocol = ATAPI_PROT_PIO; | ||
tf.lbam = sizeof(buf); | ||
|
||
ret = ata_exec_internal(dev, &tf, cdb, DMA_FROM_DEVICE, | ||
buf, sizeof(buf), 0); | ||
if (ret) | ||
return ODD_MECH_TYPE_UNSUPPORTED; | ||
|
||
if (be16_to_cpu(desc->feature_code) != 3) | ||
return ODD_MECH_TYPE_UNSUPPORTED; | ||
|
||
if (desc->mech_type == 0 && desc->load == 0 && desc->eject == 1) | ||
return ODD_MECH_TYPE_SLOT; | ||
else if (desc->mech_type == 1 && desc->load == 0 && desc->eject == 1) | ||
return ODD_MECH_TYPE_DRAWER; | ||
else | ||
return ODD_MECH_TYPE_UNSUPPORTED; | ||
} | ||
|
||
static bool odd_can_poweroff(struct ata_device *ata_dev) | ||
{ | ||
acpi_handle handle; | ||
acpi_status status; | ||
struct acpi_device *acpi_dev; | ||
|
||
handle = ata_dev_acpi_handle(ata_dev); | ||
if (!handle) | ||
return false; | ||
|
||
status = acpi_bus_get_device(handle, &acpi_dev); | ||
if (ACPI_FAILURE(status)) | ||
return false; | ||
|
||
return acpi_device_can_poweroff(acpi_dev); | ||
} | ||
|
||
void zpodd_init(struct ata_device *dev) | ||
{ | ||
enum odd_mech_type mech_type; | ||
struct zpodd *zpodd; | ||
|
||
if (dev->zpodd) | ||
return; | ||
|
||
if (!odd_can_poweroff(dev)) | ||
return; | ||
|
||
mech_type = zpodd_get_mech_type(dev); | ||
if (mech_type == ODD_MECH_TYPE_UNSUPPORTED) | ||
return; | ||
|
||
zpodd = kzalloc(sizeof(struct zpodd), GFP_KERNEL); | ||
if (!zpodd) | ||
return; | ||
|
||
zpodd->mech_type = mech_type; | ||
|
||
zpodd->dev = dev; | ||
dev->zpodd = zpodd; | ||
} | ||
|
||
void zpodd_exit(struct ata_device *dev) | ||
{ | ||
kfree(dev->zpodd); | ||
dev->zpodd = NULL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters