mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:46:16 +00:00
ata changes for 6.13
- Fix typos in comments (Yan Zhen) - Remove unused macro definitions (Damien Le Moal) - Switch back to the .remove() callback (Uwe Kleine-König) - Make use of the get_unaligned_be24() helper instead of open coding (Andy Shevchenko) - Refactor and cleanup ata_scsi_simulate() command emulation, such that all commands use ata_scsi_rbuf_fill() with its own callback (Damien Le Moal) - Improve ata_scsi_simulate() command emulation by accurately setting the SCSI command residual (number of bytes not filled) in the command reply (Damien Le Moal) - Add missing iommus property in ahci-platform device tree binding (Frank Wunderlich) -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRN+ES/c4tHlMch3DzJZDGjmcZNcgUCZzthbQAKCRDJZDGjmcZN cvgtAQDDzKLg9UQhJou7nAjrdyJi7gZBy5o0Q0KIjMOqgnmz8wEA6HC+EWOjH3Fq 3f1nwxXGKR7T+bVUZpYfB+YTB8ly+g0= =0XKN -----END PGP SIGNATURE----- Merge tag 'ata-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux Pull ata updates from Niklas Cassel: - Fix typos in comments (Yan Zhen) - Remove unused macro definitions (Damien Le Moal) - Switch back to the .remove() callback (Uwe Kleine-König) - Make use of the get_unaligned_be24() helper instead of open coding (Andy Shevchenko) - Refactor and cleanup ata_scsi_simulate() command emulation, such that all commands use ata_scsi_rbuf_fill() with its own callback (Damien Le Moal) - Improve ata_scsi_simulate() command emulation by accurately setting the SCSI command residual (number of bytes not filled) in the command reply (Damien Le Moal) - Add missing iommus property in ahci-platform device tree binding (Frank Wunderlich) * tag 'ata-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/libata/linux: dt-bindings: ata: ahci-platform: add missing iommus property ata: libata-scsi: Return residual for emulated SCSI commands ata: libata-scsi: Remove struct ata_scsi_args ata: libata-scsi: Document all VPD page inquiry actors ata: libata-scsi: Refactor ata_scsiop_maint_in() ata: libata-scsi: Refactor ata_scsiop_read_cap() ata: libata-scsi: Refactor ata_scsi_simulate() ata: libata-scsi: Refactor scsi_6_lba_len() with use of get_unaligned_be24() ata: Switch back to struct platform_driver::remove() ata: libata: Remove unused macro definitions ata: Fix typos in the comment
This commit is contained in:
commit
3d1b536c13
@ -84,6 +84,9 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^sata-port@[0-9a-f]+$":
|
||||
$ref: /schemas/ata/ahci-common.yaml#/$defs/ahci-port
|
||||
|
@ -1676,7 +1676,7 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
|
||||
/*
|
||||
* If number of MSIs is less than number of ports then Sharing Last
|
||||
* Message mode could be enforced. In this case assume that advantage
|
||||
* of multipe MSIs is negated and use single MSI mode instead.
|
||||
* of multiple MSIs is negated and use single MSI mode instead.
|
||||
*/
|
||||
if (n_ports > 1) {
|
||||
nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX,
|
||||
|
@ -571,7 +571,7 @@ static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume);
|
||||
|
||||
static struct platform_driver brcm_ahci_driver = {
|
||||
.probe = brcm_ahci_probe,
|
||||
.remove_new = brcm_ahci_remove,
|
||||
.remove = brcm_ahci_remove,
|
||||
.shutdown = brcm_ahci_shutdown,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
|
@ -402,7 +402,7 @@ MODULE_DEVICE_TABLE(of, ceva_ahci_of_match);
|
||||
|
||||
static struct platform_driver ceva_ahci_driver = {
|
||||
.probe = ceva_ahci_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = ceva_ahci_of_match,
|
||||
|
@ -238,7 +238,7 @@ MODULE_DEVICE_TABLE(of, ahci_da850_of_match);
|
||||
|
||||
static struct platform_driver ahci_da850_driver = {
|
||||
.probe = ahci_da850_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = ahci_da850_of_match,
|
||||
|
@ -182,7 +182,7 @@ MODULE_DEVICE_TABLE(of, ahci_dm816_of_match);
|
||||
|
||||
static struct platform_driver ahci_dm816_driver = {
|
||||
.probe = ahci_dm816_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = AHCI_DM816_DRV_NAME,
|
||||
.of_match_table = ahci_dm816_of_match,
|
||||
|
@ -478,7 +478,7 @@ MODULE_DEVICE_TABLE(of, ahci_dwc_of_match);
|
||||
|
||||
static struct platform_driver ahci_dwc_driver = {
|
||||
.probe = ahci_dwc_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.shutdown = ahci_platform_shutdown,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
|
@ -511,7 +511,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
|
||||
|
||||
if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) {
|
||||
/*
|
||||
* set PHY Paremeters, two steps to configure the GPR13,
|
||||
* set PHY Parameters, two steps to configure the GPR13,
|
||||
* one write for rest of parameters, mask of first write
|
||||
* is 0x07ffffff, and the other one write for setting
|
||||
* the mpll_clk_en.
|
||||
@ -1027,7 +1027,7 @@ static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume);
|
||||
|
||||
static struct platform_driver imx_ahci_driver = {
|
||||
.probe = imx_ahci_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = imx_ahci_of_match,
|
||||
|
@ -174,7 +174,7 @@ MODULE_DEVICE_TABLE(of, ahci_of_match);
|
||||
|
||||
static struct platform_driver mtk_ahci_driver = {
|
||||
.probe = mtk_ahci_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = ahci_of_match,
|
||||
|
@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match);
|
||||
|
||||
static struct platform_driver ahci_mvebu_driver = {
|
||||
.probe = ahci_mvebu_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.suspend = ahci_mvebu_suspend,
|
||||
.resume = ahci_mvebu_resume,
|
||||
.driver = {
|
||||
|
@ -96,7 +96,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
|
||||
|
||||
static struct platform_driver ahci_driver = {
|
||||
.probe = ahci_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.shutdown = ahci_platform_shutdown,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
|
@ -357,7 +357,7 @@ static SIMPLE_DEV_PM_OPS(ahci_qoriq_pm_ops, ahci_platform_suspend,
|
||||
|
||||
static struct platform_driver ahci_qoriq_driver = {
|
||||
.probe = ahci_qoriq_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = ahci_qoriq_of_match,
|
||||
|
@ -185,7 +185,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
|
||||
|
||||
static struct platform_driver ahci_seattle_driver = {
|
||||
.probe = ahci_seattle_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.acpi_match_table = ahci_acpi_match,
|
||||
|
@ -238,7 +238,7 @@ static struct platform_driver st_ahci_driver = {
|
||||
.of_match_table = st_ahci_match,
|
||||
},
|
||||
.probe = st_ahci_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
};
|
||||
module_platform_driver(st_ahci_driver);
|
||||
|
||||
|
@ -292,7 +292,7 @@ MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match);
|
||||
|
||||
static struct platform_driver ahci_sunxi_driver = {
|
||||
.probe = ahci_sunxi_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = ahci_sunxi_of_match,
|
||||
|
@ -608,7 +608,7 @@ static int tegra_ahci_probe(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver tegra_ahci_driver = {
|
||||
.probe = tegra_ahci_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = tegra_ahci_of_match,
|
||||
|
@ -534,7 +534,7 @@ static int xgene_ahci_softreset(struct ata_link *link, unsigned int *class,
|
||||
|
||||
/**
|
||||
* xgene_ahci_handle_broken_edge_irq - Handle the broken irq.
|
||||
* @host: Host that recieved the irq
|
||||
* @host: Host that received the irq
|
||||
* @irq_masked: HOST_IRQ_STAT value
|
||||
*
|
||||
* For hardware with broken edge trigger latch
|
||||
@ -859,7 +859,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver xgene_ahci_driver = {
|
||||
.probe = xgene_ahci_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = xgene_ahci_of_match,
|
||||
|
@ -86,7 +86,7 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
|
||||
* @dev: ATA device ACPI event occurred (can be NULL)
|
||||
* @event: ACPI event which occurred
|
||||
*
|
||||
* All ACPI bay / device realted events end up in this function. If
|
||||
* All ACPI bay / device related events end up in this function. If
|
||||
* the event is port-wide @dev is NULL. If the event is specific to a
|
||||
* device, @dev points to it.
|
||||
*
|
||||
@ -832,7 +832,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
|
||||
dev->flags |= ATA_DFLAG_ACPI_PENDING;
|
||||
}
|
||||
} else {
|
||||
/* SATA _GTF needs to be evaulated after _SDD and
|
||||
/* SATA _GTF needs to be evaluated after _SDD and
|
||||
* there's no reason to evaluate IDE _GTF early
|
||||
* without _STM. Clear cache and schedule _GTF.
|
||||
*/
|
||||
|
@ -1334,17 +1334,8 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc)
|
||||
*/
|
||||
static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
|
||||
{
|
||||
u64 lba = 0;
|
||||
u32 len;
|
||||
|
||||
lba |= ((u64)(cdb[1] & 0x1f)) << 16;
|
||||
lba |= ((u64)cdb[2]) << 8;
|
||||
lba |= ((u64)cdb[3]);
|
||||
|
||||
len = cdb[4];
|
||||
|
||||
*plba = lba;
|
||||
*plen = len;
|
||||
*plba = get_unaligned_be24(&cdb[1]) & 0x1fffff;
|
||||
*plen = cdb[4];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1781,15 +1772,10 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
}
|
||||
|
||||
struct ata_scsi_args {
|
||||
struct ata_device *dev;
|
||||
u16 *id;
|
||||
struct scsi_cmnd *cmd;
|
||||
};
|
||||
|
||||
/**
|
||||
* ata_scsi_rbuf_fill - wrapper for SCSI command simulators
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @actor: Callback hook for desired SCSI command simulator
|
||||
*
|
||||
* Takes care of the hard work of simulating a SCSI command...
|
||||
@ -1802,30 +1788,32 @@ struct ata_scsi_args {
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
|
||||
unsigned int (*actor)(struct ata_scsi_args *args, u8 *rbuf))
|
||||
static void ata_scsi_rbuf_fill(struct ata_device *dev, struct scsi_cmnd *cmd,
|
||||
unsigned int (*actor)(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf))
|
||||
{
|
||||
unsigned int rc;
|
||||
struct scsi_cmnd *cmd = args->cmd;
|
||||
unsigned long flags;
|
||||
unsigned int len;
|
||||
|
||||
spin_lock_irqsave(&ata_scsi_rbuf_lock, flags);
|
||||
|
||||
memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE);
|
||||
rc = actor(args, ata_scsi_rbuf);
|
||||
if (rc == 0)
|
||||
len = actor(dev, cmd, ata_scsi_rbuf);
|
||||
if (len) {
|
||||
sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
|
||||
ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE);
|
||||
cmd->result = SAM_STAT_GOOD;
|
||||
if (scsi_bufflen(cmd) > len)
|
||||
scsi_set_resid(cmd, scsi_bufflen(cmd) - len);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags);
|
||||
|
||||
if (rc == 0)
|
||||
cmd->result = SAM_STAT_GOOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_inq_std - Simulate INQUIRY command
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* ata_scsiop_inq_std - Simulate standard INQUIRY command
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Returns standard device identification data associated
|
||||
@ -1834,7 +1822,8 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_inq_std(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
static const u8 versions[] = {
|
||||
0x00,
|
||||
@ -1875,40 +1864,45 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* Set the SCSI Removable Media Bit (RMB) if the ATA removable media
|
||||
* device bit (obsolete since ATA-8 ACS) is set.
|
||||
*/
|
||||
if (ata_id_removable(args->id))
|
||||
if (ata_id_removable(dev->id))
|
||||
hdr[1] |= (1 << 7);
|
||||
|
||||
if (args->dev->class == ATA_DEV_ZAC) {
|
||||
if (dev->class == ATA_DEV_ZAC) {
|
||||
hdr[0] = TYPE_ZBC;
|
||||
hdr[2] = 0x7; /* claim SPC-5 version compatibility */
|
||||
}
|
||||
|
||||
if (args->dev->flags & ATA_DFLAG_CDL)
|
||||
if (dev->flags & ATA_DFLAG_CDL)
|
||||
hdr[2] = 0xd; /* claim SPC-6 version compatibility */
|
||||
|
||||
memcpy(rbuf, hdr, sizeof(hdr));
|
||||
memcpy(&rbuf[8], "ATA ", 8);
|
||||
ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);
|
||||
ata_id_string(dev->id, &rbuf[16], ATA_ID_PROD, 16);
|
||||
|
||||
/* From SAT, use last 2 words from fw rev unless they are spaces */
|
||||
ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV + 2, 4);
|
||||
ata_id_string(dev->id, &rbuf[32], ATA_ID_FW_REV + 2, 4);
|
||||
if (strncmp(&rbuf[32], " ", 4) == 0)
|
||||
ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4);
|
||||
ata_id_string(dev->id, &rbuf[32], ATA_ID_FW_REV, 4);
|
||||
|
||||
if (rbuf[32] == 0 || rbuf[32] == ' ')
|
||||
memcpy(&rbuf[32], "n/a ", 4);
|
||||
|
||||
if (ata_id_zoned_cap(args->id) || args->dev->class == ATA_DEV_ZAC)
|
||||
if (ata_id_zoned_cap(dev->id) || dev->class == ATA_DEV_ZAC)
|
||||
memcpy(rbuf + 58, versions_zbc, sizeof(versions_zbc));
|
||||
else
|
||||
memcpy(rbuf + 58, versions, sizeof(versions));
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* Include all 8 possible version descriptors, even if not all of
|
||||
* them are popoulated.
|
||||
*/
|
||||
return 96;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_inq_00 - Simulate INQUIRY VPD page 0, list of pages
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Returns list of inquiry VPD pages available.
|
||||
@ -1916,7 +1910,8 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_inq_00(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
int i, num_pages = 0;
|
||||
static const u8 pages[] = {
|
||||
@ -1933,18 +1928,20 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
|
||||
|
||||
for (i = 0; i < sizeof(pages); i++) {
|
||||
if (pages[i] == 0xb6 &&
|
||||
!(args->dev->flags & ATA_DFLAG_ZAC))
|
||||
!(dev->flags & ATA_DFLAG_ZAC))
|
||||
continue;
|
||||
rbuf[num_pages + 4] = pages[i];
|
||||
num_pages++;
|
||||
}
|
||||
rbuf[3] = num_pages; /* number of supported VPD pages */
|
||||
return 0;
|
||||
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_inq_80 - Simulate INQUIRY VPD page 80, device serial number
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Returns ATA device serial number.
|
||||
@ -1952,7 +1949,8 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_inq_80(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
static const u8 hdr[] = {
|
||||
0,
|
||||
@ -1962,14 +1960,16 @@ static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf)
|
||||
};
|
||||
|
||||
memcpy(rbuf, hdr, sizeof(hdr));
|
||||
ata_id_string(args->id, (unsigned char *) &rbuf[4],
|
||||
ata_id_string(dev->id, (unsigned char *) &rbuf[4],
|
||||
ATA_ID_SERNO, ATA_ID_SERNO_LEN);
|
||||
return 0;
|
||||
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_inq_83 - Simulate INQUIRY VPD page 83, device identity
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Yields two logical unit device identification designators:
|
||||
@ -1980,7 +1980,8 @@ static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_inq_83(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
const int sat_model_serial_desc_len = 68;
|
||||
int num;
|
||||
@ -1992,7 +1993,7 @@ static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf)
|
||||
rbuf[num + 0] = 2;
|
||||
rbuf[num + 3] = ATA_ID_SERNO_LEN;
|
||||
num += 4;
|
||||
ata_id_string(args->id, (unsigned char *) rbuf + num,
|
||||
ata_id_string(dev->id, (unsigned char *) rbuf + num,
|
||||
ATA_ID_SERNO, ATA_ID_SERNO_LEN);
|
||||
num += ATA_ID_SERNO_LEN;
|
||||
|
||||
@ -2004,31 +2005,33 @@ static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf)
|
||||
num += 4;
|
||||
memcpy(rbuf + num, "ATA ", 8);
|
||||
num += 8;
|
||||
ata_id_string(args->id, (unsigned char *) rbuf + num, ATA_ID_PROD,
|
||||
ata_id_string(dev->id, (unsigned char *) rbuf + num, ATA_ID_PROD,
|
||||
ATA_ID_PROD_LEN);
|
||||
num += ATA_ID_PROD_LEN;
|
||||
ata_id_string(args->id, (unsigned char *) rbuf + num, ATA_ID_SERNO,
|
||||
ata_id_string(dev->id, (unsigned char *) rbuf + num, ATA_ID_SERNO,
|
||||
ATA_ID_SERNO_LEN);
|
||||
num += ATA_ID_SERNO_LEN;
|
||||
|
||||
if (ata_id_has_wwn(args->id)) {
|
||||
if (ata_id_has_wwn(dev->id)) {
|
||||
/* SAT defined lu world wide name */
|
||||
/* piv=0, assoc=lu, code_set=binary, designator=NAA */
|
||||
rbuf[num + 0] = 1;
|
||||
rbuf[num + 1] = 3;
|
||||
rbuf[num + 3] = ATA_ID_WWN_LEN;
|
||||
num += 4;
|
||||
ata_id_string(args->id, (unsigned char *) rbuf + num,
|
||||
ata_id_string(dev->id, (unsigned char *) rbuf + num,
|
||||
ATA_ID_WWN, ATA_ID_WWN_LEN);
|
||||
num += ATA_ID_WWN_LEN;
|
||||
}
|
||||
rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */
|
||||
return 0;
|
||||
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Yields SAT-specified ATA VPD page.
|
||||
@ -2036,7 +2039,8 @@ static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_inq_89(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
rbuf[1] = 0x89; /* our page code */
|
||||
rbuf[2] = (0x238 >> 8); /* page size fixed at 238h */
|
||||
@ -2057,13 +2061,25 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)
|
||||
|
||||
rbuf[56] = ATA_CMD_ID_ATA;
|
||||
|
||||
memcpy(&rbuf[60], &args->id[0], 512);
|
||||
return 0;
|
||||
memcpy(&rbuf[60], &dev->id[0], 512);
|
||||
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
|
||||
/**
|
||||
* ata_scsiop_inq_b0 - Simulate INQUIRY VPD page B0, Block Limits
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Return data for the VPD page B0h (Block Limits).
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_b0(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
struct ata_device *dev = args->dev;
|
||||
u16 min_io_sectors;
|
||||
|
||||
rbuf[1] = 0xb0;
|
||||
@ -2076,7 +2092,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* logical than physical sector size we need to figure out what the
|
||||
* latter is.
|
||||
*/
|
||||
min_io_sectors = 1 << ata_id_log2_per_physical_sector(args->id);
|
||||
min_io_sectors = 1 << ata_id_log2_per_physical_sector(dev->id);
|
||||
put_unaligned_be16(min_io_sectors, &rbuf[6]);
|
||||
|
||||
/*
|
||||
@ -2088,7 +2104,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* that we support some form of unmap - in thise case via WRITE SAME
|
||||
* with the unmap bit set.
|
||||
*/
|
||||
if (ata_id_has_trim(args->id)) {
|
||||
if (ata_id_has_trim(dev->id)) {
|
||||
u64 max_blocks = 65535 * ATA_MAX_TRIM_RNUM;
|
||||
|
||||
if (dev->quirks & ATA_QUIRK_MAX_TRIM_128M)
|
||||
@ -2098,14 +2114,27 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf)
|
||||
put_unaligned_be32(1, &rbuf[28]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
|
||||
/**
|
||||
* ata_scsiop_inq_b1 - Simulate INQUIRY VPD page B1, Block Device
|
||||
* Characteristics
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Return data for the VPD page B1h (Block Device Characteristics).
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_b1(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
int form_factor = ata_id_form_factor(args->id);
|
||||
int media_rotation_rate = ata_id_rotation_rate(args->id);
|
||||
u8 zoned = ata_id_zoned_cap(args->id);
|
||||
int form_factor = ata_id_form_factor(dev->id);
|
||||
int media_rotation_rate = ata_id_rotation_rate(dev->id);
|
||||
u8 zoned = ata_id_zoned_cap(dev->id);
|
||||
|
||||
rbuf[1] = 0xb1;
|
||||
rbuf[3] = 0x3c;
|
||||
@ -2115,21 +2144,52 @@ static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
|
||||
if (zoned)
|
||||
rbuf[8] = (zoned << 4);
|
||||
|
||||
return 0;
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
static unsigned int ata_scsiop_inq_b2(struct ata_scsi_args *args, u8 *rbuf)
|
||||
/**
|
||||
* ata_scsiop_inq_b2 - Simulate INQUIRY VPD page B2, Logical Block
|
||||
* Provisioning
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Return data for the VPD page B2h (Logical Block Provisioning).
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_b2(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
/* SCSI Thin Provisioning VPD page: SBC-3 rev 22 or later */
|
||||
rbuf[1] = 0xb2;
|
||||
rbuf[3] = 0x4;
|
||||
rbuf[5] = 1 << 6; /* TPWS */
|
||||
|
||||
return 0;
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf)
|
||||
/**
|
||||
* ata_scsiop_inq_b6 - Simulate INQUIRY VPD page B6, Zoned Block Device
|
||||
* Characteristics
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Return data for the VPD page B2h (Zoned Block Device Characteristics).
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_b6(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
if (!(dev->flags & ATA_DFLAG_ZAC)) {
|
||||
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* zbc-r05 SCSI Zoned Block device characteristics VPD page
|
||||
*/
|
||||
@ -2139,21 +2199,39 @@ static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf)
|
||||
/*
|
||||
* URSWRZ bit is only meaningful for host-managed ZAC drives
|
||||
*/
|
||||
if (args->dev->zac_zoned_cap & 1)
|
||||
if (dev->zac_zoned_cap & 1)
|
||||
rbuf[4] |= 1;
|
||||
put_unaligned_be32(args->dev->zac_zones_optimal_open, &rbuf[8]);
|
||||
put_unaligned_be32(args->dev->zac_zones_optimal_nonseq, &rbuf[12]);
|
||||
put_unaligned_be32(args->dev->zac_zones_max_open, &rbuf[16]);
|
||||
put_unaligned_be32(dev->zac_zones_optimal_open, &rbuf[8]);
|
||||
put_unaligned_be32(dev->zac_zones_optimal_nonseq, &rbuf[12]);
|
||||
put_unaligned_be32(dev->zac_zones_max_open, &rbuf[16]);
|
||||
|
||||
return 0;
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf)
|
||||
/**
|
||||
* ata_scsiop_inq_b9 - Simulate INQUIRY VPD page B9, Concurrent Positioning
|
||||
* Ranges
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Return data for the VPD page B9h (Concurrent Positioning Ranges).
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inq_b9(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
struct ata_cpr_log *cpr_log = args->dev->cpr_log;
|
||||
struct ata_cpr_log *cpr_log = dev->cpr_log;
|
||||
u8 *desc = &rbuf[64];
|
||||
int i;
|
||||
|
||||
if (!cpr_log) {
|
||||
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */
|
||||
rbuf[1] = 0xb9;
|
||||
put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[2]);
|
||||
@ -2165,7 +2243,58 @@ static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf)
|
||||
put_unaligned_be64(cpr_log->cpr[i].num_lbas, &desc[16]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return get_unaligned_be16(&rbuf[2]) + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_inquiry - Simulate INQUIRY command
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Returns data associated with an INQUIRY command output.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_inquiry(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
const u8 *scsicmd = cmd->cmnd;
|
||||
|
||||
/* is CmdDt set? */
|
||||
if (scsicmd[1] & 2) {
|
||||
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is EVPD clear? */
|
||||
if ((scsicmd[1] & 1) == 0)
|
||||
return ata_scsiop_inq_std(dev, cmd, rbuf);
|
||||
|
||||
switch (scsicmd[2]) {
|
||||
case 0x00:
|
||||
return ata_scsiop_inq_00(dev, cmd, rbuf);
|
||||
case 0x80:
|
||||
return ata_scsiop_inq_80(dev, cmd, rbuf);
|
||||
case 0x83:
|
||||
return ata_scsiop_inq_83(dev, cmd, rbuf);
|
||||
case 0x89:
|
||||
return ata_scsiop_inq_89(dev, cmd, rbuf);
|
||||
case 0xb0:
|
||||
return ata_scsiop_inq_b0(dev, cmd, rbuf);
|
||||
case 0xb1:
|
||||
return ata_scsiop_inq_b1(dev, cmd, rbuf);
|
||||
case 0xb2:
|
||||
return ata_scsiop_inq_b2(dev, cmd, rbuf);
|
||||
case 0xb6:
|
||||
return ata_scsiop_inq_b6(dev, cmd, rbuf);
|
||||
case 0xb9:
|
||||
return ata_scsiop_inq_b9(dev, cmd, rbuf);
|
||||
default:
|
||||
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2388,7 +2517,8 @@ static unsigned int ata_msense_rw_recovery(u8 *buf, bool changeable)
|
||||
|
||||
/**
|
||||
* ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Simulate MODE SENSE commands. Assume this is invoked for direct
|
||||
@ -2398,10 +2528,10 @@ static unsigned int ata_msense_rw_recovery(u8 *buf, bool changeable)
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_mode_sense(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
struct ata_device *dev = args->dev;
|
||||
u8 *scsicmd = args->cmd->cmnd, *p = rbuf;
|
||||
u8 *scsicmd = cmd->cmnd, *p = rbuf;
|
||||
static const u8 sat_blk_desc[] = {
|
||||
0, 0, 0, 0, /* number of blocks: sat unspecified */
|
||||
0,
|
||||
@ -2466,17 +2596,17 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
|
||||
break;
|
||||
|
||||
case CACHE_MPAGE:
|
||||
p += ata_msense_caching(args->id, p, page_control == 1);
|
||||
p += ata_msense_caching(dev->id, p, page_control == 1);
|
||||
break;
|
||||
|
||||
case CONTROL_MPAGE:
|
||||
p += ata_msense_control(args->dev, p, spg, page_control == 1);
|
||||
p += ata_msense_control(dev, p, spg, page_control == 1);
|
||||
break;
|
||||
|
||||
case ALL_MPAGES:
|
||||
p += ata_msense_rw_recovery(p, page_control == 1);
|
||||
p += ata_msense_caching(args->id, p, page_control == 1);
|
||||
p += ata_msense_control(args->dev, p, spg, page_control == 1);
|
||||
p += ata_msense_caching(dev->id, p, page_control == 1);
|
||||
p += ata_msense_control(dev, p, spg, page_control == 1);
|
||||
break;
|
||||
|
||||
default: /* invalid page code */
|
||||
@ -2494,29 +2624,33 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
|
||||
rbuf[3] = sizeof(sat_blk_desc);
|
||||
memcpy(rbuf + 4, sat_blk_desc, sizeof(sat_blk_desc));
|
||||
}
|
||||
} else {
|
||||
put_unaligned_be16(p - rbuf - 2, &rbuf[0]);
|
||||
rbuf[3] |= dpofua;
|
||||
if (ebd) {
|
||||
rbuf[7] = sizeof(sat_blk_desc);
|
||||
memcpy(rbuf + 8, sat_blk_desc, sizeof(sat_blk_desc));
|
||||
}
|
||||
|
||||
return rbuf[0] + 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
put_unaligned_be16(p - rbuf - 2, &rbuf[0]);
|
||||
rbuf[3] |= dpofua;
|
||||
if (ebd) {
|
||||
rbuf[7] = sizeof(sat_blk_desc);
|
||||
memcpy(rbuf + 8, sat_blk_desc, sizeof(sat_blk_desc));
|
||||
}
|
||||
|
||||
return get_unaligned_be16(&rbuf[0]) + 2;
|
||||
|
||||
invalid_fld:
|
||||
ata_scsi_set_invalid_field(dev, args->cmd, fp, bp);
|
||||
return 1;
|
||||
ata_scsi_set_invalid_field(dev, cmd, fp, bp);
|
||||
return 0;
|
||||
|
||||
saving_not_supp:
|
||||
ata_scsi_set_sense(dev, args->cmd, ILLEGAL_REQUEST, 0x39, 0x0);
|
||||
ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x39, 0x0);
|
||||
/* "Saving parameters not supported" */
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_read_cap - Simulate READ CAPACITY[ 16] commands
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Simulate READ CAPACITY commands.
|
||||
@ -2524,9 +2658,10 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* LOCKING:
|
||||
* None.
|
||||
*/
|
||||
static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_read_cap(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
struct ata_device *dev = args->dev;
|
||||
u8 *scsicmd = cmd->cmnd;
|
||||
u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */
|
||||
u32 sector_size; /* physical sector size in bytes */
|
||||
u8 log2_per_phys;
|
||||
@ -2536,7 +2671,7 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
|
||||
log2_per_phys = ata_id_log2_per_physical_sector(dev->id);
|
||||
lowest_aligned = ata_id_logical_sector_offset(dev->id, log2_per_phys);
|
||||
|
||||
if (args->cmd->cmnd[0] == READ_CAPACITY) {
|
||||
if (scsicmd[0] == READ_CAPACITY) {
|
||||
if (last_lba >= 0xffffffffULL)
|
||||
last_lba = 0xffffffff;
|
||||
|
||||
@ -2551,48 +2686,59 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
|
||||
rbuf[5] = sector_size >> (8 * 2);
|
||||
rbuf[6] = sector_size >> (8 * 1);
|
||||
rbuf[7] = sector_size;
|
||||
} else {
|
||||
/* sector count, 64-bit */
|
||||
rbuf[0] = last_lba >> (8 * 7);
|
||||
rbuf[1] = last_lba >> (8 * 6);
|
||||
rbuf[2] = last_lba >> (8 * 5);
|
||||
rbuf[3] = last_lba >> (8 * 4);
|
||||
rbuf[4] = last_lba >> (8 * 3);
|
||||
rbuf[5] = last_lba >> (8 * 2);
|
||||
rbuf[6] = last_lba >> (8 * 1);
|
||||
rbuf[7] = last_lba;
|
||||
|
||||
/* sector size */
|
||||
rbuf[ 8] = sector_size >> (8 * 3);
|
||||
rbuf[ 9] = sector_size >> (8 * 2);
|
||||
rbuf[10] = sector_size >> (8 * 1);
|
||||
rbuf[11] = sector_size;
|
||||
|
||||
rbuf[12] = 0;
|
||||
rbuf[13] = log2_per_phys;
|
||||
rbuf[14] = (lowest_aligned >> 8) & 0x3f;
|
||||
rbuf[15] = lowest_aligned;
|
||||
|
||||
if (ata_id_has_trim(args->id) &&
|
||||
!(dev->quirks & ATA_QUIRK_NOTRIM)) {
|
||||
rbuf[14] |= 0x80; /* LBPME */
|
||||
|
||||
if (ata_id_has_zero_after_trim(args->id) &&
|
||||
dev->quirks & ATA_QUIRK_ZERO_AFTER_TRIM) {
|
||||
ata_dev_info(dev, "Enabling discard_zeroes_data\n");
|
||||
rbuf[14] |= 0x40; /* LBPRZ */
|
||||
}
|
||||
}
|
||||
if (ata_id_zoned_cap(args->id) ||
|
||||
args->dev->class == ATA_DEV_ZAC)
|
||||
rbuf[12] = (1 << 4); /* RC_BASIS */
|
||||
return 8;
|
||||
}
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* READ CAPACITY 16 command is defined as a service action
|
||||
* (SERVICE_ACTION_IN_16 command).
|
||||
*/
|
||||
if (scsicmd[0] != SERVICE_ACTION_IN_16 ||
|
||||
(scsicmd[1] & 0x1f) != SAI_READ_CAPACITY_16) {
|
||||
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sector count, 64-bit */
|
||||
rbuf[0] = last_lba >> (8 * 7);
|
||||
rbuf[1] = last_lba >> (8 * 6);
|
||||
rbuf[2] = last_lba >> (8 * 5);
|
||||
rbuf[3] = last_lba >> (8 * 4);
|
||||
rbuf[4] = last_lba >> (8 * 3);
|
||||
rbuf[5] = last_lba >> (8 * 2);
|
||||
rbuf[6] = last_lba >> (8 * 1);
|
||||
rbuf[7] = last_lba;
|
||||
|
||||
/* sector size */
|
||||
rbuf[ 8] = sector_size >> (8 * 3);
|
||||
rbuf[ 9] = sector_size >> (8 * 2);
|
||||
rbuf[10] = sector_size >> (8 * 1);
|
||||
rbuf[11] = sector_size;
|
||||
|
||||
if (ata_id_zoned_cap(dev->id) || dev->class == ATA_DEV_ZAC)
|
||||
rbuf[12] = (1 << 4); /* RC_BASIS */
|
||||
rbuf[13] = log2_per_phys;
|
||||
rbuf[14] = (lowest_aligned >> 8) & 0x3f;
|
||||
rbuf[15] = lowest_aligned;
|
||||
|
||||
if (ata_id_has_trim(dev->id) && !(dev->quirks & ATA_QUIRK_NOTRIM)) {
|
||||
rbuf[14] |= 0x80; /* LBPME */
|
||||
|
||||
if (ata_id_has_zero_after_trim(dev->id) &&
|
||||
dev->quirks & ATA_QUIRK_ZERO_AFTER_TRIM) {
|
||||
ata_dev_info(dev, "Enabling discard_zeroes_data\n");
|
||||
rbuf[14] |= 0x40; /* LBPRZ */
|
||||
}
|
||||
}
|
||||
|
||||
return 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsiop_report_luns - Simulate REPORT LUNS command
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Simulate REPORT LUNS command.
|
||||
@ -2600,11 +2746,12 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_report_luns(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
rbuf[3] = 8; /* just one lun, LUN 0, size 8 bytes */
|
||||
|
||||
return 0;
|
||||
return 16;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3312,7 +3459,8 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
|
||||
|
||||
/**
|
||||
* ata_scsiop_maint_in - Simulate a subset of MAINTENANCE_IN
|
||||
* @args: device MAINTENANCE_IN data / SCSI command of interest.
|
||||
* @dev: Target device.
|
||||
* @cmd: SCSI command of interest.
|
||||
* @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
|
||||
*
|
||||
* Yields a subset to satisfy scsi_report_opcode()
|
||||
@ -3320,17 +3468,21 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(host lock)
|
||||
*/
|
||||
static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf)
|
||||
static unsigned int ata_scsiop_maint_in(struct ata_device *dev,
|
||||
struct scsi_cmnd *cmd, u8 *rbuf)
|
||||
{
|
||||
struct ata_device *dev = args->dev;
|
||||
u8 *cdb = args->cmd->cmnd;
|
||||
u8 *cdb = cmd->cmnd;
|
||||
u8 supported = 0, cdlp = 0, rwcdlp = 0;
|
||||
unsigned int err = 0;
|
||||
|
||||
if ((cdb[1] & 0x1f) != MI_REPORT_SUPPORTED_OPERATION_CODES) {
|
||||
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cdb[2] != 1 && cdb[2] != 3) {
|
||||
ata_dev_warn(dev, "invalid command format %d\n", cdb[2]);
|
||||
err = 2;
|
||||
goto out;
|
||||
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (cdb[3]) {
|
||||
@ -3398,11 +3550,12 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
out:
|
||||
|
||||
/* One command format */
|
||||
rbuf[0] = rwcdlp;
|
||||
rbuf[1] = cdlp | supported;
|
||||
return err;
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4262,78 +4415,26 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
|
||||
|
||||
void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
|
||||
{
|
||||
struct ata_scsi_args args;
|
||||
const u8 *scsicmd = cmd->cmnd;
|
||||
u8 tmp8;
|
||||
|
||||
args.dev = dev;
|
||||
args.id = dev->id;
|
||||
args.cmd = cmd;
|
||||
|
||||
switch(scsicmd[0]) {
|
||||
case INQUIRY:
|
||||
if (scsicmd[1] & 2) /* is CmdDt set? */
|
||||
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
|
||||
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
|
||||
else switch (scsicmd[2]) {
|
||||
case 0x00:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00);
|
||||
break;
|
||||
case 0x80:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80);
|
||||
break;
|
||||
case 0x83:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83);
|
||||
break;
|
||||
case 0x89:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89);
|
||||
break;
|
||||
case 0xb0:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b0);
|
||||
break;
|
||||
case 0xb1:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b1);
|
||||
break;
|
||||
case 0xb2:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
|
||||
break;
|
||||
case 0xb6:
|
||||
if (dev->flags & ATA_DFLAG_ZAC)
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6);
|
||||
else
|
||||
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
|
||||
break;
|
||||
case 0xb9:
|
||||
if (dev->cpr_log)
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b9);
|
||||
else
|
||||
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
|
||||
break;
|
||||
default:
|
||||
ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
|
||||
break;
|
||||
}
|
||||
ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_inquiry);
|
||||
break;
|
||||
|
||||
case MODE_SENSE:
|
||||
case MODE_SENSE_10:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense);
|
||||
ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_mode_sense);
|
||||
break;
|
||||
|
||||
case READ_CAPACITY:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
|
||||
break;
|
||||
|
||||
case SERVICE_ACTION_IN_16:
|
||||
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
|
||||
else
|
||||
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
|
||||
ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_read_cap);
|
||||
break;
|
||||
|
||||
case REPORT_LUNS:
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns);
|
||||
ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_report_luns);
|
||||
break;
|
||||
|
||||
case REQUEST_SENSE:
|
||||
@ -4361,10 +4462,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
|
||||
break;
|
||||
|
||||
case MAINTENANCE_IN:
|
||||
if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES)
|
||||
ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in);
|
||||
else
|
||||
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
|
||||
ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_maint_in);
|
||||
break;
|
||||
|
||||
/* all other commands */
|
||||
|
@ -964,7 +964,7 @@ MODULE_DEVICE_TABLE(of, arasan_cf_id_table);
|
||||
|
||||
static struct platform_driver arasan_cf_driver = {
|
||||
.probe = arasan_cf_probe,
|
||||
.remove_new = arasan_cf_remove,
|
||||
.remove = arasan_cf_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.pm = &arasan_cf_pm_ops,
|
||||
|
@ -1015,7 +1015,7 @@ static struct platform_driver ep93xx_pata_platform_driver = {
|
||||
.of_match_table = ep93xx_pata_of_ids,
|
||||
},
|
||||
.probe = ep93xx_pata_probe,
|
||||
.remove_new = ep93xx_pata_remove,
|
||||
.remove = ep93xx_pata_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ep93xx_pata_platform_driver);
|
||||
|
@ -225,8 +225,8 @@ static void pata_falcon_remove_one(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver pata_falcon_driver = {
|
||||
.probe = pata_falcon_init_one,
|
||||
.remove_new = pata_falcon_remove_one,
|
||||
.driver = {
|
||||
.remove = pata_falcon_remove_one,
|
||||
.driver = {
|
||||
.name = "atari-falcon-ide",
|
||||
},
|
||||
};
|
||||
|
@ -557,7 +557,7 @@ static struct platform_driver pata_ftide010_driver = {
|
||||
.of_match_table = pata_ftide010_of_match,
|
||||
},
|
||||
.probe = pata_ftide010_probe,
|
||||
.remove_new = pata_ftide010_remove,
|
||||
.remove = pata_ftide010_remove,
|
||||
};
|
||||
module_platform_driver(pata_ftide010_driver);
|
||||
|
||||
|
@ -202,9 +202,9 @@ static void pata_gayle_remove_one(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver pata_gayle_driver = {
|
||||
.probe = pata_gayle_init_one,
|
||||
.remove_new = pata_gayle_remove_one,
|
||||
.driver = {
|
||||
.name = "amiga-gayle-ide",
|
||||
.remove = pata_gayle_remove_one,
|
||||
.driver = {
|
||||
.name = "amiga-gayle-ide",
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -249,7 +249,7 @@ MODULE_DEVICE_TABLE(of, imx_pata_dt_ids);
|
||||
|
||||
static struct platform_driver pata_imx_driver = {
|
||||
.probe = pata_imx_probe,
|
||||
.remove_new = pata_imx_remove,
|
||||
.remove = pata_imx_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = imx_pata_dt_ids,
|
||||
|
@ -81,7 +81,7 @@ static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev)
|
||||
int control = 0;
|
||||
|
||||
/*
|
||||
* See Intel Document 298600-004 for the timing programing rules
|
||||
* See Intel Document 298600-004 for the timing programming rules
|
||||
* for PIIX/ICH. The 8213 is a clone so very similar
|
||||
*/
|
||||
|
||||
|
@ -298,7 +298,7 @@ static struct platform_driver ixp4xx_pata_platform_driver = {
|
||||
.of_match_table = ixp4xx_pata_of_match,
|
||||
},
|
||||
.probe = ixp4xx_pata_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
};
|
||||
|
||||
module_platform_driver(ixp4xx_pata_platform_driver);
|
||||
|
@ -854,7 +854,7 @@ static const struct of_device_id mpc52xx_ata_of_match[] = {
|
||||
|
||||
static struct platform_driver mpc52xx_ata_of_platform_driver = {
|
||||
.probe = mpc52xx_ata_probe,
|
||||
.remove_new = mpc52xx_ata_remove,
|
||||
.remove = mpc52xx_ata_remove,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.suspend = mpc52xx_ata_suspend,
|
||||
.resume = mpc52xx_ata_resume,
|
||||
|
@ -183,7 +183,7 @@ static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev)
|
||||
reg_tim.s.ale = 0;
|
||||
/* Not used */
|
||||
reg_tim.s.page = 0;
|
||||
/* Time after IORDY to coninue to assert the data */
|
||||
/* Time after IORDY to continue to assert the data */
|
||||
reg_tim.s.wait = 0;
|
||||
/* Time to wait to complete the cycle. */
|
||||
reg_tim.s.pause = pause;
|
||||
|
@ -89,7 +89,7 @@ static struct platform_driver pata_of_platform_driver = {
|
||||
.of_match_table = pata_of_platform_match,
|
||||
},
|
||||
.probe = pata_of_platform_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
};
|
||||
|
||||
module_platform_driver(pata_of_platform_driver);
|
||||
|
@ -70,7 +70,7 @@ static void oldpiix_set_piomode (struct ata_port *ap, struct ata_device *adev)
|
||||
int control = 0;
|
||||
|
||||
/*
|
||||
* See Intel Document 298600-004 for the timing programing rules
|
||||
* See Intel Document 298600-004 for the timing programming rules
|
||||
* for PIIX/ICH. Note that the early PIIX does not have the slave
|
||||
* timing port at 0x44.
|
||||
*/
|
||||
|
@ -223,7 +223,7 @@ static int pata_platform_probe(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver pata_platform_driver = {
|
||||
.probe = pata_platform_probe,
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
|
@ -306,7 +306,7 @@ static void pxa_ata_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver pxa_ata_driver = {
|
||||
.probe = pxa_ata_probe,
|
||||
.remove_new = pxa_ata_remove,
|
||||
.remove = pxa_ata_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
|
@ -45,7 +45,7 @@ static void radisys_set_piomode (struct ata_port *ap, struct ata_device *adev)
|
||||
int control = 0;
|
||||
|
||||
/*
|
||||
* See Intel Document 298600-004 for the timing programing rules
|
||||
* See Intel Document 298600-004 for the timing programming rules
|
||||
* for PIIX/ICH. Note that the early PIIX does not have the slave
|
||||
* timing port at 0x44. The Radisys is a relative of the PIIX
|
||||
* but not the same so be careful.
|
||||
|
@ -164,7 +164,7 @@ static void rb532_pata_driver_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver rb532_pata_platform_driver = {
|
||||
.probe = rb532_pata_driver_probe,
|
||||
.remove_new = rb532_pata_driver_remove,
|
||||
.remove = rb532_pata_driver_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
|
@ -1240,7 +1240,7 @@ static struct platform_driver sata_dwc_driver = {
|
||||
.of_match_table = sata_dwc_match,
|
||||
},
|
||||
.probe = sata_dwc_probe,
|
||||
.remove_new = sata_dwc_remove,
|
||||
.remove = sata_dwc_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(sata_dwc_driver);
|
||||
|
@ -1589,7 +1589,7 @@ static struct platform_driver fsl_sata_driver = {
|
||||
.of_match_table = fsl_sata_match,
|
||||
},
|
||||
.probe = sata_fsl_probe,
|
||||
.remove_new = sata_fsl_remove,
|
||||
.remove = sata_fsl_remove,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.suspend = sata_fsl_suspend,
|
||||
.resume = sata_fsl_resume,
|
||||
|
@ -425,7 +425,7 @@ static struct platform_driver gemini_sata_driver = {
|
||||
.of_match_table = gemini_sata_of_match,
|
||||
},
|
||||
.probe = gemini_sata_probe,
|
||||
.remove_new = gemini_sata_remove,
|
||||
.remove = gemini_sata_remove,
|
||||
};
|
||||
module_platform_driver(gemini_sata_driver);
|
||||
|
||||
|
@ -614,12 +614,12 @@ static SIMPLE_DEV_PM_OPS(ahci_highbank_pm_ops,
|
||||
ahci_highbank_suspend, ahci_highbank_resume);
|
||||
|
||||
static struct platform_driver ahci_highbank_driver = {
|
||||
.remove_new = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = "highbank-ahci",
|
||||
.of_match_table = ahci_of_match,
|
||||
.pm = &ahci_highbank_pm_ops,
|
||||
},
|
||||
.remove = ata_platform_remove_one,
|
||||
.driver = {
|
||||
.name = "highbank-ahci",
|
||||
.of_match_table = ahci_of_match,
|
||||
.pm = &ahci_highbank_pm_ops,
|
||||
},
|
||||
.probe = ahci_highbank_probe,
|
||||
};
|
||||
|
||||
|
@ -4255,7 +4255,7 @@ MODULE_DEVICE_TABLE(of, mv_sata_dt_ids);
|
||||
|
||||
static struct platform_driver mv_platform_driver = {
|
||||
.probe = mv_platform_probe,
|
||||
.remove_new = mv_platform_remove,
|
||||
.remove = mv_platform_remove,
|
||||
.suspend = mv_platform_suspend,
|
||||
.resume = mv_platform_resume,
|
||||
.driver = {
|
||||
|
@ -1009,7 +1009,7 @@ static const struct dev_pm_ops sata_rcar_pm_ops = {
|
||||
|
||||
static struct platform_driver sata_rcar_driver = {
|
||||
.probe = sata_rcar_probe,
|
||||
.remove_new = sata_rcar_remove,
|
||||
.remove = sata_rcar_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.of_match_table = sata_rcar_match,
|
||||
|
@ -270,9 +270,7 @@ enum {
|
||||
|
||||
/* bits 24:31 of host->flags are reserved for LLD specific flags */
|
||||
|
||||
/* various lengths of time */
|
||||
ATA_TMOUT_BOOT = 30000, /* heuristic */
|
||||
ATA_TMOUT_BOOT_QUICK = 7000, /* heuristic */
|
||||
/* Various lengths of time */
|
||||
ATA_TMOUT_INTERNAL_QUICK = 5000,
|
||||
ATA_TMOUT_MAX_PARK = 30000,
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user