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:
Linus Torvalds 2024-11-18 16:45:28 -08:00
commit 3d1b536c13
42 changed files with 362 additions and 263 deletions

View File

@ -84,6 +84,9 @@ properties:
minItems: 1 minItems: 1
maxItems: 3 maxItems: 3
iommus:
maxItems: 1
patternProperties: patternProperties:
"^sata-port@[0-9a-f]+$": "^sata-port@[0-9a-f]+$":
$ref: /schemas/ata/ahci-common.yaml#/$defs/ahci-port $ref: /schemas/ata/ahci-common.yaml#/$defs/ahci-port

View File

@ -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 * If number of MSIs is less than number of ports then Sharing Last
* Message mode could be enforced. In this case assume that advantage * 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) { if (n_ports > 1) {
nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX, nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX,

View File

@ -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 = { static struct platform_driver brcm_ahci_driver = {
.probe = brcm_ahci_probe, .probe = brcm_ahci_probe,
.remove_new = brcm_ahci_remove, .remove = brcm_ahci_remove,
.shutdown = brcm_ahci_shutdown, .shutdown = brcm_ahci_shutdown,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,

View File

@ -402,7 +402,7 @@ MODULE_DEVICE_TABLE(of, ceva_ahci_of_match);
static struct platform_driver ceva_ahci_driver = { static struct platform_driver ceva_ahci_driver = {
.probe = ceva_ahci_probe, .probe = ceva_ahci_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ceva_ahci_of_match, .of_match_table = ceva_ahci_of_match,

View File

@ -238,7 +238,7 @@ MODULE_DEVICE_TABLE(of, ahci_da850_of_match);
static struct platform_driver ahci_da850_driver = { static struct platform_driver ahci_da850_driver = {
.probe = ahci_da850_probe, .probe = ahci_da850_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ahci_da850_of_match, .of_match_table = ahci_da850_of_match,

View File

@ -182,7 +182,7 @@ MODULE_DEVICE_TABLE(of, ahci_dm816_of_match);
static struct platform_driver ahci_dm816_driver = { static struct platform_driver ahci_dm816_driver = {
.probe = ahci_dm816_probe, .probe = ahci_dm816_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = AHCI_DM816_DRV_NAME, .name = AHCI_DM816_DRV_NAME,
.of_match_table = ahci_dm816_of_match, .of_match_table = ahci_dm816_of_match,

View File

@ -478,7 +478,7 @@ MODULE_DEVICE_TABLE(of, ahci_dwc_of_match);
static struct platform_driver ahci_dwc_driver = { static struct platform_driver ahci_dwc_driver = {
.probe = ahci_dwc_probe, .probe = ahci_dwc_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.shutdown = ahci_platform_shutdown, .shutdown = ahci_platform_shutdown,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,

View File

@ -511,7 +511,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
if (imxpriv->type == AHCI_IMX6Q || imxpriv->type == AHCI_IMX6QP) { 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 * one write for rest of parameters, mask of first write
* is 0x07ffffff, and the other one write for setting * is 0x07ffffff, and the other one write for setting
* the mpll_clk_en. * 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 = { static struct platform_driver imx_ahci_driver = {
.probe = imx_ahci_probe, .probe = imx_ahci_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = imx_ahci_of_match, .of_match_table = imx_ahci_of_match,

View File

@ -174,7 +174,7 @@ MODULE_DEVICE_TABLE(of, ahci_of_match);
static struct platform_driver mtk_ahci_driver = { static struct platform_driver mtk_ahci_driver = {
.probe = mtk_ahci_probe, .probe = mtk_ahci_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ahci_of_match, .of_match_table = ahci_of_match,

View File

@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match);
static struct platform_driver ahci_mvebu_driver = { static struct platform_driver ahci_mvebu_driver = {
.probe = ahci_mvebu_probe, .probe = ahci_mvebu_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.suspend = ahci_mvebu_suspend, .suspend = ahci_mvebu_suspend,
.resume = ahci_mvebu_resume, .resume = ahci_mvebu_resume,
.driver = { .driver = {

View File

@ -96,7 +96,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
static struct platform_driver ahci_driver = { static struct platform_driver ahci_driver = {
.probe = ahci_probe, .probe = ahci_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.shutdown = ahci_platform_shutdown, .shutdown = ahci_platform_shutdown,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,

View File

@ -357,7 +357,7 @@ static SIMPLE_DEV_PM_OPS(ahci_qoriq_pm_ops, ahci_platform_suspend,
static struct platform_driver ahci_qoriq_driver = { static struct platform_driver ahci_qoriq_driver = {
.probe = ahci_qoriq_probe, .probe = ahci_qoriq_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ahci_qoriq_of_match, .of_match_table = ahci_qoriq_of_match,

View File

@ -185,7 +185,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);
static struct platform_driver ahci_seattle_driver = { static struct platform_driver ahci_seattle_driver = {
.probe = ahci_seattle_probe, .probe = ahci_seattle_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.acpi_match_table = ahci_acpi_match, .acpi_match_table = ahci_acpi_match,

View File

@ -238,7 +238,7 @@ static struct platform_driver st_ahci_driver = {
.of_match_table = st_ahci_match, .of_match_table = st_ahci_match,
}, },
.probe = st_ahci_probe, .probe = st_ahci_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
}; };
module_platform_driver(st_ahci_driver); module_platform_driver(st_ahci_driver);

View File

@ -292,7 +292,7 @@ MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match);
static struct platform_driver ahci_sunxi_driver = { static struct platform_driver ahci_sunxi_driver = {
.probe = ahci_sunxi_probe, .probe = ahci_sunxi_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ahci_sunxi_of_match, .of_match_table = ahci_sunxi_of_match,

View File

@ -608,7 +608,7 @@ deinit_controller:
static struct platform_driver tegra_ahci_driver = { static struct platform_driver tegra_ahci_driver = {
.probe = tegra_ahci_probe, .probe = tegra_ahci_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = tegra_ahci_of_match, .of_match_table = tegra_ahci_of_match,

View File

@ -534,7 +534,7 @@ softreset_retry:
/** /**
* xgene_ahci_handle_broken_edge_irq - Handle the broken irq. * 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 * @irq_masked: HOST_IRQ_STAT value
* *
* For hardware with broken edge trigger latch * For hardware with broken edge trigger latch
@ -859,7 +859,7 @@ disable_resources:
static struct platform_driver xgene_ahci_driver = { static struct platform_driver xgene_ahci_driver = {
.probe = xgene_ahci_probe, .probe = xgene_ahci_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = xgene_ahci_of_match, .of_match_table = xgene_ahci_of_match,

View File

@ -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) * @dev: ATA device ACPI event occurred (can be NULL)
* @event: ACPI event which occurred * @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 * the event is port-wide @dev is NULL. If the event is specific to a
* device, @dev points to it. * device, @dev points to it.
* *
@ -832,7 +832,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
dev->flags |= ATA_DFLAG_ACPI_PENDING; dev->flags |= ATA_DFLAG_ACPI_PENDING;
} }
} else { } 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 * there's no reason to evaluate IDE _GTF early
* without _STM. Clear cache and schedule _GTF. * without _STM. Clear cache and schedule _GTF.
*/ */

View File

@ -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) static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{ {
u64 lba = 0; *plba = get_unaligned_be24(&cdb[1]) & 0x1fffff;
u32 len; *plen = cdb[4];
lba |= ((u64)(cdb[1] & 0x1f)) << 16;
lba |= ((u64)cdb[2]) << 8;
lba |= ((u64)cdb[3]);
len = cdb[4];
*plba = lba;
*plen = len;
} }
/** /**
@ -1781,15 +1772,10 @@ defer:
return SCSI_MLQUEUE_HOST_BUSY; 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 * 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 * @actor: Callback hook for desired SCSI command simulator
* *
* Takes care of the hard work of simulating a SCSI command... * Takes care of the hard work of simulating a SCSI command...
@ -1802,30 +1788,32 @@ struct ata_scsi_args {
* LOCKING: * LOCKING:
* spin_lock_irqsave(host lock) * spin_lock_irqsave(host lock)
*/ */
static void ata_scsi_rbuf_fill(struct ata_scsi_args *args, static void ata_scsi_rbuf_fill(struct ata_device *dev, struct scsi_cmnd *cmd,
unsigned int (*actor)(struct ata_scsi_args *args, u8 *rbuf)) 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 long flags;
unsigned int len;
spin_lock_irqsave(&ata_scsi_rbuf_lock, flags); spin_lock_irqsave(&ata_scsi_rbuf_lock, flags);
memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE); memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE);
rc = actor(args, ata_scsi_rbuf); len = actor(dev, cmd, ata_scsi_rbuf);
if (rc == 0) if (len) {
sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE); 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); spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags);
if (rc == 0)
cmd->result = SAM_STAT_GOOD;
} }
/** /**
* ata_scsiop_inq_std - Simulate INQUIRY command * ata_scsiop_inq_std - Simulate standard INQUIRY 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Returns standard device identification data associated * Returns standard device identification data associated
@ -1834,7 +1822,8 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
* LOCKING: * LOCKING:
* spin_lock_irqsave(host lock) * 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[] = { static const u8 versions[] = {
0x00, 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 * Set the SCSI Removable Media Bit (RMB) if the ATA removable media
* device bit (obsolete since ATA-8 ACS) is set. * 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); hdr[1] |= (1 << 7);
if (args->dev->class == ATA_DEV_ZAC) { if (dev->class == ATA_DEV_ZAC) {
hdr[0] = TYPE_ZBC; hdr[0] = TYPE_ZBC;
hdr[2] = 0x7; /* claim SPC-5 version compatibility */ 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 */ hdr[2] = 0xd; /* claim SPC-6 version compatibility */
memcpy(rbuf, hdr, sizeof(hdr)); memcpy(rbuf, hdr, sizeof(hdr));
memcpy(&rbuf[8], "ATA ", 8); 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 */ /* 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) 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] == ' ') if (rbuf[32] == 0 || rbuf[32] == ' ')
memcpy(&rbuf[32], "n/a ", 4); 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)); memcpy(rbuf + 58, versions_zbc, sizeof(versions_zbc));
else else
memcpy(rbuf + 58, versions, sizeof(versions)); 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 * 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Returns list of inquiry VPD pages available. * 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: * LOCKING:
* spin_lock_irqsave(host lock) * 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; int i, num_pages = 0;
static const u8 pages[] = { 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++) { for (i = 0; i < sizeof(pages); i++) {
if (pages[i] == 0xb6 && if (pages[i] == 0xb6 &&
!(args->dev->flags & ATA_DFLAG_ZAC)) !(dev->flags & ATA_DFLAG_ZAC))
continue; continue;
rbuf[num_pages + 4] = pages[i]; rbuf[num_pages + 4] = pages[i];
num_pages++; num_pages++;
} }
rbuf[3] = num_pages; /* number of supported VPD 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 * 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Returns ATA device serial number. * Returns ATA device serial number.
@ -1952,7 +1949,8 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
* LOCKING: * LOCKING:
* spin_lock_irqsave(host lock) * 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[] = { static const u8 hdr[] = {
0, 0,
@ -1962,14 +1960,16 @@ static unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf)
}; };
memcpy(rbuf, hdr, sizeof(hdr)); 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); 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 * 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Yields two logical unit device identification designators: * 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: * LOCKING:
* spin_lock_irqsave(host lock) * 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; const int sat_model_serial_desc_len = 68;
int num; 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 + 0] = 2;
rbuf[num + 3] = ATA_ID_SERNO_LEN; rbuf[num + 3] = ATA_ID_SERNO_LEN;
num += 4; 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); ATA_ID_SERNO, ATA_ID_SERNO_LEN);
num += 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; num += 4;
memcpy(rbuf + num, "ATA ", 8); memcpy(rbuf + num, "ATA ", 8);
num += 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); ATA_ID_PROD_LEN);
num += 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); ATA_ID_SERNO_LEN);
num += 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 */ /* SAT defined lu world wide name */
/* piv=0, assoc=lu, code_set=binary, designator=NAA */ /* piv=0, assoc=lu, code_set=binary, designator=NAA */
rbuf[num + 0] = 1; rbuf[num + 0] = 1;
rbuf[num + 1] = 3; rbuf[num + 1] = 3;
rbuf[num + 3] = ATA_ID_WWN_LEN; rbuf[num + 3] = ATA_ID_WWN_LEN;
num += 4; 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); ATA_ID_WWN, ATA_ID_WWN_LEN);
num += ATA_ID_WWN_LEN; num += ATA_ID_WWN_LEN;
} }
rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */ 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 * 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Yields SAT-specified ATA VPD page. * 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: * LOCKING:
* spin_lock_irqsave(host lock) * 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[1] = 0x89; /* our page code */
rbuf[2] = (0x238 >> 8); /* page size fixed at 238h */ 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; rbuf[56] = ATA_CMD_ID_ATA;
memcpy(&rbuf[60], &args->id[0], 512); memcpy(&rbuf[60], &dev->id[0], 512);
return 0;
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; u16 min_io_sectors;
rbuf[1] = 0xb0; 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 * logical than physical sector size we need to figure out what the
* latter is. * 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]); 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 * that we support some form of unmap - in thise case via WRITE SAME
* with the unmap bit set. * 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; u64 max_blocks = 65535 * ATA_MAX_TRIM_RNUM;
if (dev->quirks & ATA_QUIRK_MAX_TRIM_128M) 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]); 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 form_factor = ata_id_form_factor(dev->id);
int media_rotation_rate = ata_id_rotation_rate(args->id); int media_rotation_rate = ata_id_rotation_rate(dev->id);
u8 zoned = ata_id_zoned_cap(args->id); u8 zoned = ata_id_zoned_cap(dev->id);
rbuf[1] = 0xb1; rbuf[1] = 0xb1;
rbuf[3] = 0x3c; rbuf[3] = 0x3c;
@ -2115,21 +2144,52 @@ static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
if (zoned) if (zoned)
rbuf[8] = (zoned << 4); 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 */ /* SCSI Thin Provisioning VPD page: SBC-3 rev 22 or later */
rbuf[1] = 0xb2; rbuf[1] = 0xb2;
rbuf[3] = 0x4; rbuf[3] = 0x4;
rbuf[5] = 1 << 6; /* TPWS */ 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 * 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 * 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; rbuf[4] |= 1;
put_unaligned_be32(args->dev->zac_zones_optimal_open, &rbuf[8]); put_unaligned_be32(dev->zac_zones_optimal_open, &rbuf[8]);
put_unaligned_be32(args->dev->zac_zones_optimal_nonseq, &rbuf[12]); put_unaligned_be32(dev->zac_zones_optimal_nonseq, &rbuf[12]);
put_unaligned_be32(args->dev->zac_zones_max_open, &rbuf[16]); 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]; u8 *desc = &rbuf[64];
int i; 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 */ /* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */
rbuf[1] = 0xb9; rbuf[1] = 0xb9;
put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[2]); 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]); 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 * 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Simulate MODE SENSE commands. Assume this is invoked for direct * 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: * LOCKING:
* spin_lock_irqsave(host lock) * 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 = cmd->cmnd, *p = rbuf;
u8 *scsicmd = args->cmd->cmnd, *p = rbuf;
static const u8 sat_blk_desc[] = { static const u8 sat_blk_desc[] = {
0, 0, 0, 0, /* number of blocks: sat unspecified */ 0, 0, 0, 0, /* number of blocks: sat unspecified */
0, 0,
@ -2466,17 +2596,17 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
break; break;
case CACHE_MPAGE: case CACHE_MPAGE:
p += ata_msense_caching(args->id, p, page_control == 1); p += ata_msense_caching(dev->id, p, page_control == 1);
break; break;
case CONTROL_MPAGE: 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; break;
case ALL_MPAGES: case ALL_MPAGES:
p += ata_msense_rw_recovery(p, page_control == 1); p += ata_msense_rw_recovery(p, page_control == 1);
p += ata_msense_caching(args->id, p, page_control == 1); p += ata_msense_caching(dev->id, p, page_control == 1);
p += ata_msense_control(args->dev, p, spg, page_control == 1); p += ata_msense_control(dev, p, spg, page_control == 1);
break; break;
default: /* invalid page code */ 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); rbuf[3] = sizeof(sat_blk_desc);
memcpy(rbuf + 4, sat_blk_desc, sizeof(sat_blk_desc)); memcpy(rbuf + 4, sat_blk_desc, sizeof(sat_blk_desc));
} }
} else {
put_unaligned_be16(p - rbuf - 2, &rbuf[0]); return rbuf[0] + 1;
rbuf[3] |= dpofua;
if (ebd) {
rbuf[7] = sizeof(sat_blk_desc);
memcpy(rbuf + 8, sat_blk_desc, sizeof(sat_blk_desc));
}
} }
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: invalid_fld:
ata_scsi_set_invalid_field(dev, args->cmd, fp, bp); ata_scsi_set_invalid_field(dev, cmd, fp, bp);
return 1; return 0;
saving_not_supp: 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" */ /* "Saving parameters not supported" */
return 1; return 0;
} }
/** /**
* ata_scsiop_read_cap - Simulate READ CAPACITY[ 16] commands * 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Simulate READ CAPACITY commands. * Simulate READ CAPACITY commands.
@ -2524,9 +2658,10 @@ saving_not_supp:
* LOCKING: * LOCKING:
* None. * 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 */ u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */
u32 sector_size; /* physical sector size in bytes */ u32 sector_size; /* physical sector size in bytes */
u8 log2_per_phys; 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); log2_per_phys = ata_id_log2_per_physical_sector(dev->id);
lowest_aligned = ata_id_logical_sector_offset(dev->id, log2_per_phys); 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) if (last_lba >= 0xffffffffULL)
last_lba = 0xffffffff; 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[5] = sector_size >> (8 * 2);
rbuf[6] = sector_size >> (8 * 1); rbuf[6] = sector_size >> (8 * 1);
rbuf[7] = sector_size; 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 */ return 8;
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 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 * 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Simulate REPORT LUNS command. * Simulate REPORT LUNS command.
@ -2600,11 +2746,12 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
* LOCKING: * LOCKING:
* spin_lock_irqsave(host lock) * 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 */ rbuf[3] = 8; /* just one lun, LUN 0, size 8 bytes */
return 0; return 16;
} }
/* /*
@ -3312,7 +3459,8 @@ invalid_opcode:
/** /**
* ata_scsiop_maint_in - Simulate a subset of MAINTENANCE_IN * 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. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
* *
* Yields a subset to satisfy scsi_report_opcode() * Yields a subset to satisfy scsi_report_opcode()
@ -3320,17 +3468,21 @@ invalid_opcode:
* LOCKING: * LOCKING:
* spin_lock_irqsave(host lock) * 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 = cmd->cmnd;
u8 *cdb = args->cmd->cmnd;
u8 supported = 0, cdlp = 0, rwcdlp = 0; 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) { if (cdb[2] != 1 && cdb[2] != 3) {
ata_dev_warn(dev, "invalid command format %d\n", cdb[2]); ata_dev_warn(dev, "invalid command format %d\n", cdb[2]);
err = 2; ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
goto out; return 0;
} }
switch (cdb[3]) { switch (cdb[3]) {
@ -3398,11 +3550,12 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf)
default: default:
break; break;
} }
out:
/* One command format */ /* One command format */
rbuf[0] = rwcdlp; rbuf[0] = rwcdlp;
rbuf[1] = cdlp | supported; 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) void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
{ {
struct ata_scsi_args args;
const u8 *scsicmd = cmd->cmnd; const u8 *scsicmd = cmd->cmnd;
u8 tmp8; u8 tmp8;
args.dev = dev;
args.id = dev->id;
args.cmd = cmd;
switch(scsicmd[0]) { switch(scsicmd[0]) {
case INQUIRY: case INQUIRY:
if (scsicmd[1] & 2) /* is CmdDt set? */ ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_inquiry);
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;
}
break; break;
case MODE_SENSE: case MODE_SENSE:
case MODE_SENSE_10: case MODE_SENSE_10:
ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense); ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_mode_sense);
break; break;
case READ_CAPACITY: case READ_CAPACITY:
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
break;
case SERVICE_ACTION_IN_16: case SERVICE_ACTION_IN_16:
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_read_cap);
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
else
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
break; break;
case REPORT_LUNS: case REPORT_LUNS:
ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns); ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_report_luns);
break; break;
case REQUEST_SENSE: case REQUEST_SENSE:
@ -4361,10 +4462,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
break; break;
case MAINTENANCE_IN: case MAINTENANCE_IN:
if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES) ata_scsi_rbuf_fill(dev, cmd, ata_scsiop_maint_in);
ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in);
else
ata_scsi_set_invalid_field(dev, cmd, 1, 0xff);
break; break;
/* all other commands */ /* all other commands */

View File

@ -964,7 +964,7 @@ MODULE_DEVICE_TABLE(of, arasan_cf_id_table);
static struct platform_driver arasan_cf_driver = { static struct platform_driver arasan_cf_driver = {
.probe = arasan_cf_probe, .probe = arasan_cf_probe,
.remove_new = arasan_cf_remove, .remove = arasan_cf_remove,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pm = &arasan_cf_pm_ops, .pm = &arasan_cf_pm_ops,

View File

@ -1015,7 +1015,7 @@ static struct platform_driver ep93xx_pata_platform_driver = {
.of_match_table = ep93xx_pata_of_ids, .of_match_table = ep93xx_pata_of_ids,
}, },
.probe = ep93xx_pata_probe, .probe = ep93xx_pata_probe,
.remove_new = ep93xx_pata_remove, .remove = ep93xx_pata_remove,
}; };
module_platform_driver(ep93xx_pata_platform_driver); module_platform_driver(ep93xx_pata_platform_driver);

View File

@ -225,8 +225,8 @@ static void pata_falcon_remove_one(struct platform_device *pdev)
static struct platform_driver pata_falcon_driver = { static struct platform_driver pata_falcon_driver = {
.probe = pata_falcon_init_one, .probe = pata_falcon_init_one,
.remove_new = pata_falcon_remove_one, .remove = pata_falcon_remove_one,
.driver = { .driver = {
.name = "atari-falcon-ide", .name = "atari-falcon-ide",
}, },
}; };

View File

@ -557,7 +557,7 @@ static struct platform_driver pata_ftide010_driver = {
.of_match_table = pata_ftide010_of_match, .of_match_table = pata_ftide010_of_match,
}, },
.probe = pata_ftide010_probe, .probe = pata_ftide010_probe,
.remove_new = pata_ftide010_remove, .remove = pata_ftide010_remove,
}; };
module_platform_driver(pata_ftide010_driver); module_platform_driver(pata_ftide010_driver);

View File

@ -202,9 +202,9 @@ static void pata_gayle_remove_one(struct platform_device *pdev)
static struct platform_driver pata_gayle_driver = { static struct platform_driver pata_gayle_driver = {
.probe = pata_gayle_init_one, .probe = pata_gayle_init_one,
.remove_new = pata_gayle_remove_one, .remove = pata_gayle_remove_one,
.driver = { .driver = {
.name = "amiga-gayle-ide", .name = "amiga-gayle-ide",
}, },
}; };

View File

@ -249,7 +249,7 @@ MODULE_DEVICE_TABLE(of, imx_pata_dt_ids);
static struct platform_driver pata_imx_driver = { static struct platform_driver pata_imx_driver = {
.probe = pata_imx_probe, .probe = pata_imx_probe,
.remove_new = pata_imx_remove, .remove = pata_imx_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = imx_pata_dt_ids, .of_match_table = imx_pata_dt_ids,

View File

@ -81,7 +81,7 @@ static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev)
int control = 0; 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 * for PIIX/ICH. The 8213 is a clone so very similar
*/ */

View File

@ -298,7 +298,7 @@ static struct platform_driver ixp4xx_pata_platform_driver = {
.of_match_table = ixp4xx_pata_of_match, .of_match_table = ixp4xx_pata_of_match,
}, },
.probe = ixp4xx_pata_probe, .probe = ixp4xx_pata_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
}; };
module_platform_driver(ixp4xx_pata_platform_driver); module_platform_driver(ixp4xx_pata_platform_driver);

View File

@ -854,7 +854,7 @@ static const struct of_device_id mpc52xx_ata_of_match[] = {
static struct platform_driver mpc52xx_ata_of_platform_driver = { static struct platform_driver mpc52xx_ata_of_platform_driver = {
.probe = mpc52xx_ata_probe, .probe = mpc52xx_ata_probe,
.remove_new = mpc52xx_ata_remove, .remove = mpc52xx_ata_remove,
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
.suspend = mpc52xx_ata_suspend, .suspend = mpc52xx_ata_suspend,
.resume = mpc52xx_ata_resume, .resume = mpc52xx_ata_resume,

View File

@ -183,7 +183,7 @@ static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev)
reg_tim.s.ale = 0; reg_tim.s.ale = 0;
/* Not used */ /* Not used */
reg_tim.s.page = 0; 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; reg_tim.s.wait = 0;
/* Time to wait to complete the cycle. */ /* Time to wait to complete the cycle. */
reg_tim.s.pause = pause; reg_tim.s.pause = pause;

View File

@ -89,7 +89,7 @@ static struct platform_driver pata_of_platform_driver = {
.of_match_table = pata_of_platform_match, .of_match_table = pata_of_platform_match,
}, },
.probe = pata_of_platform_probe, .probe = pata_of_platform_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
}; };
module_platform_driver(pata_of_platform_driver); module_platform_driver(pata_of_platform_driver);

View File

@ -70,7 +70,7 @@ static void oldpiix_set_piomode (struct ata_port *ap, struct ata_device *adev)
int control = 0; 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 * for PIIX/ICH. Note that the early PIIX does not have the slave
* timing port at 0x44. * timing port at 0x44.
*/ */

View File

@ -223,7 +223,7 @@ static int pata_platform_probe(struct platform_device *pdev)
static struct platform_driver pata_platform_driver = { static struct platform_driver pata_platform_driver = {
.probe = pata_platform_probe, .probe = pata_platform_probe,
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
}, },

View File

@ -306,7 +306,7 @@ static void pxa_ata_remove(struct platform_device *pdev)
static struct platform_driver pxa_ata_driver = { static struct platform_driver pxa_ata_driver = {
.probe = pxa_ata_probe, .probe = pxa_ata_probe,
.remove_new = pxa_ata_remove, .remove = pxa_ata_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
}, },

View File

@ -45,7 +45,7 @@ static void radisys_set_piomode (struct ata_port *ap, struct ata_device *adev)
int control = 0; 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 * 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 * timing port at 0x44. The Radisys is a relative of the PIIX
* but not the same so be careful. * but not the same so be careful.

View File

@ -164,7 +164,7 @@ static void rb532_pata_driver_remove(struct platform_device *pdev)
static struct platform_driver rb532_pata_platform_driver = { static struct platform_driver rb532_pata_platform_driver = {
.probe = rb532_pata_driver_probe, .probe = rb532_pata_driver_probe,
.remove_new = rb532_pata_driver_remove, .remove = rb532_pata_driver_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
}, },

View File

@ -1240,7 +1240,7 @@ static struct platform_driver sata_dwc_driver = {
.of_match_table = sata_dwc_match, .of_match_table = sata_dwc_match,
}, },
.probe = sata_dwc_probe, .probe = sata_dwc_probe,
.remove_new = sata_dwc_remove, .remove = sata_dwc_remove,
}; };
module_platform_driver(sata_dwc_driver); module_platform_driver(sata_dwc_driver);

View File

@ -1589,7 +1589,7 @@ static struct platform_driver fsl_sata_driver = {
.of_match_table = fsl_sata_match, .of_match_table = fsl_sata_match,
}, },
.probe = sata_fsl_probe, .probe = sata_fsl_probe,
.remove_new = sata_fsl_remove, .remove = sata_fsl_remove,
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
.suspend = sata_fsl_suspend, .suspend = sata_fsl_suspend,
.resume = sata_fsl_resume, .resume = sata_fsl_resume,

View File

@ -425,7 +425,7 @@ static struct platform_driver gemini_sata_driver = {
.of_match_table = gemini_sata_of_match, .of_match_table = gemini_sata_of_match,
}, },
.probe = gemini_sata_probe, .probe = gemini_sata_probe,
.remove_new = gemini_sata_remove, .remove = gemini_sata_remove,
}; };
module_platform_driver(gemini_sata_driver); module_platform_driver(gemini_sata_driver);

View File

@ -614,12 +614,12 @@ static SIMPLE_DEV_PM_OPS(ahci_highbank_pm_ops,
ahci_highbank_suspend, ahci_highbank_resume); ahci_highbank_suspend, ahci_highbank_resume);
static struct platform_driver ahci_highbank_driver = { static struct platform_driver ahci_highbank_driver = {
.remove_new = ata_platform_remove_one, .remove = ata_platform_remove_one,
.driver = { .driver = {
.name = "highbank-ahci", .name = "highbank-ahci",
.of_match_table = ahci_of_match, .of_match_table = ahci_of_match,
.pm = &ahci_highbank_pm_ops, .pm = &ahci_highbank_pm_ops,
}, },
.probe = ahci_highbank_probe, .probe = ahci_highbank_probe,
}; };

View File

@ -4255,7 +4255,7 @@ MODULE_DEVICE_TABLE(of, mv_sata_dt_ids);
static struct platform_driver mv_platform_driver = { static struct platform_driver mv_platform_driver = {
.probe = mv_platform_probe, .probe = mv_platform_probe,
.remove_new = mv_platform_remove, .remove = mv_platform_remove,
.suspend = mv_platform_suspend, .suspend = mv_platform_suspend,
.resume = mv_platform_resume, .resume = mv_platform_resume,
.driver = { .driver = {

View File

@ -1009,7 +1009,7 @@ static const struct dev_pm_ops sata_rcar_pm_ops = {
static struct platform_driver sata_rcar_driver = { static struct platform_driver sata_rcar_driver = {
.probe = sata_rcar_probe, .probe = sata_rcar_probe,
.remove_new = sata_rcar_remove, .remove = sata_rcar_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = sata_rcar_match, .of_match_table = sata_rcar_match,

View File

@ -270,9 +270,7 @@ enum {
/* bits 24:31 of host->flags are reserved for LLD specific flags */ /* bits 24:31 of host->flags are reserved for LLD specific flags */
/* various lengths of time */ /* Various lengths of time */
ATA_TMOUT_BOOT = 30000, /* heuristic */
ATA_TMOUT_BOOT_QUICK = 7000, /* heuristic */
ATA_TMOUT_INTERNAL_QUICK = 5000, ATA_TMOUT_INTERNAL_QUICK = 5000,
ATA_TMOUT_MAX_PARK = 30000, ATA_TMOUT_MAX_PARK = 30000,