Message ID | 20211027022223.183838-4-damien.lemoal@wdc.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | Initial support for multi-actuator HDDs | expand |
Hi Damien, On Wed, 27 Oct 2021, Damien Le Moal wrote: > Add support to discover if an ATA device supports the Concurrent > Positioning Ranges data log (address 0x47), indicating that the device > is capable of seeking to multiple different locations in parallel using > multiple actuators serving different LBA ranges. > > Also add support to translate the concurrent positioning ranges log > into its equivalent Concurrent Positioning Ranges VPD page B9h in > libata-scsi.c. > > The format of the Concurrent Positioning Ranges Log is defined in ACS-5 > r9. > > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Thanks for your patch, which is now commit fe22e1c2f705676a ("libata: support concurrent positioning ranges log") upstream. During resume from s2ram on Renesas Salvator-XS, I now see more scary messages than before: ata1: link resume succeeded after 1 retries ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) +ata1.00: qc timeout (cmd 0x2f) +ata1.00: Read log page 0x00 failed, Emask 0x4 +ata1.00: ATA Identify Device Log not supported +ata1.00: failed to set xfermode (err_mask=0x40) ata1: link resume succeeded after 1 retries ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) +ata1.00: ATA Identify Device Log not supported +ata1.00: ATA Identify Device Log not supported ata1.00: configured for UDMA/133 I guess this is expected? The hard drive (old Maxtor 6L160M0 that received a third life as a test bed for Renesas SATA regression testing) seems to still work fine. Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On 2021/11/02 19:40, Geert Uytterhoeven wrote: > Hi Damien, > > On Wed, 27 Oct 2021, Damien Le Moal wrote: >> Add support to discover if an ATA device supports the Concurrent >> Positioning Ranges data log (address 0x47), indicating that the device >> is capable of seeking to multiple different locations in parallel using >> multiple actuators serving different LBA ranges. >> >> Also add support to translate the concurrent positioning ranges log >> into its equivalent Concurrent Positioning Ranges VPD page B9h in >> libata-scsi.c. >> >> The format of the Concurrent Positioning Ranges Log is defined in ACS-5 >> r9. >> >> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> > > Thanks for your patch, which is now commit fe22e1c2f705676a ("libata: > support concurrent positioning ranges log") upstream. > > During resume from s2ram on Renesas Salvator-XS, I now see more scary > messages than before: > > ata1: link resume succeeded after 1 retries > ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > +ata1.00: qc timeout (cmd 0x2f) > +ata1.00: Read log page 0x00 failed, Emask 0x4 > +ata1.00: ATA Identify Device Log not supported > +ata1.00: failed to set xfermode (err_mask=0x40) > ata1: link resume succeeded after 1 retries > ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > +ata1.00: ATA Identify Device Log not supported > +ata1.00: ATA Identify Device Log not supported > ata1.00: configured for UDMA/133 > > I guess this is expected? Nope, it is not. The problem is actually not the concurrent positioning log, or any other log, being supported or not. Notice the qc timeout ? On device scan after coming out of sleep, or even simply doing a rmmod ahci+modprobe ahci, the read log commands issued during device revalidate timeout fairly easily as they are issued while the drive is not necessarilly fully restarted yet. These errors happen fairly easily due to the command timeout setting in libata being too short, I think, for the "restart" case. On a clean boot, they do not happen as longer timeouts are used in that case. I identified this problem recently while testing stuff: I was doing rmmod of ata modules and then modprobe of newly compiled modules for tests and noticed these timeouts. Increasing the timeout values, they disappear. I am however still scratching my head about the best way to address this. Still digging about this to first make sure this is really about timeouts being set too short. > > The hard drive (old Maxtor 6L160M0 that received a third life as a test > bed for Renesas SATA regression testing) seems to still work fine. I have plenty of brand new drives in my box that show similar error patterns. The drive is not at fault and libata recovers so the user may not notice the error. I didn't notice for a while too... > > Thanks! > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like that. > -- Linus Torvalds >
Hi Damien, On Tue, Nov 2, 2021 at 12:42 PM Damien Le Moal <damien.lemoal@opensource.wdc.com> wrote: > On 2021/11/02 19:40, Geert Uytterhoeven wrote: > > On Wed, 27 Oct 2021, Damien Le Moal wrote: > >> Add support to discover if an ATA device supports the Concurrent > >> Positioning Ranges data log (address 0x47), indicating that the device > >> is capable of seeking to multiple different locations in parallel using > >> multiple actuators serving different LBA ranges. > >> > >> Also add support to translate the concurrent positioning ranges log > >> into its equivalent Concurrent Positioning Ranges VPD page B9h in > >> libata-scsi.c. > >> > >> The format of the Concurrent Positioning Ranges Log is defined in ACS-5 > >> r9. > >> > >> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> > > > > Thanks for your patch, which is now commit fe22e1c2f705676a ("libata: > > support concurrent positioning ranges log") upstream. > > > > During resume from s2ram on Renesas Salvator-XS, I now see more scary > > messages than before: > > > > ata1: link resume succeeded after 1 retries > > ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > > +ata1.00: qc timeout (cmd 0x2f) > > +ata1.00: Read log page 0x00 failed, Emask 0x4 > > +ata1.00: ATA Identify Device Log not supported > > +ata1.00: failed to set xfermode (err_mask=0x40) > > ata1: link resume succeeded after 1 retries > > ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > > +ata1.00: ATA Identify Device Log not supported > > +ata1.00: ATA Identify Device Log not supported > > ata1.00: configured for UDMA/133 > > > > I guess this is expected? > > Nope, it is not. The problem is actually not the concurrent positioning log, or > any other log, being supported or not. > > Notice the qc timeout ? On device scan after coming out of sleep, or even simply > doing a rmmod ahci+modprobe ahci, the read log commands issued during device > revalidate timeout fairly easily as they are issued while the drive is not > necessarilly fully restarted yet. These errors happen fairly easily due to the > command timeout setting in libata being too short, I think, for the "restart" > case. On a clean boot, they do not happen as longer timeouts are used in that case. > > I identified this problem recently while testing stuff: I was doing rmmod of ata > modules and then modprobe of newly compiled modules for tests and noticed these > timeouts. Increasing the timeout values, they disappear. I am however still > scratching my head about the best way to address this. Still digging about this > to first make sure this is really about timeouts being set too short. There's indeed something timing-related going on. Sometimes I get during resume (s2idle or s2ram): ata1.00: qc timeout (cmd 0x2f) ata1.00: Read log page 0x00 failed, Emask 0x4 ata1.00: ATA Identify Device Log not supported ata1.00: failed to set xfermode (err_mask=0x40) ata1.00: limiting speed to UDMA/133:PIO3 ata1: link resume succeeded after 1 retries ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) ata1.00: NODEV after polling detection ata1.00: revalidation failed (errno=-2) ata1.00: disabled ata1: link resume succeeded after 1 retries ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) sd 0:0:0:0: [sda] Start/Stop Unit failed: Result: hostbyte=0x04 driverbyte=DRIVER_OK sd 0:0:0:0: [sda] Read Capacity(16) failed: Result: hostbyte=0x04 driverbyte=DRIVER_OK sd 0:0:0:0: [sda] Sense not available. sd 0:0:0:0: [sda] Read Capacity(10) failed: Result: hostbyte=0x04 driverbyte=DRIVER_OK sd 0:0:0:0: [sda] Sense not available. sd 0:0:0:0: [sda] 0 512-byte logical blocks: (0 B/0 B) sda: detected capacity change from 320173056 to 0 after which the drive is no longer functional... Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On Tue, 2021-11-02 at 15:02 +0100, Geert Uytterhoeven wrote: > Hi Damien, > > On Tue, Nov 2, 2021 at 12:42 PM Damien Le Moal > <damien.lemoal@opensource.wdc.com> wrote: > > On 2021/11/02 19:40, Geert Uytterhoeven wrote: > > > On Wed, 27 Oct 2021, Damien Le Moal wrote: > > > > Add support to discover if an ATA device supports the Concurrent > > > > Positioning Ranges data log (address 0x47), indicating that the device > > > > is capable of seeking to multiple different locations in parallel using > > > > multiple actuators serving different LBA ranges. > > > > > > > > Also add support to translate the concurrent positioning ranges log > > > > into its equivalent Concurrent Positioning Ranges VPD page B9h in > > > > libata-scsi.c. > > > > > > > > The format of the Concurrent Positioning Ranges Log is defined in ACS-5 > > > > r9. > > > > > > > > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> > > > > > > Thanks for your patch, which is now commit fe22e1c2f705676a ("libata: > > > support concurrent positioning ranges log") upstream. > > > > > > During resume from s2ram on Renesas Salvator-XS, I now see more scary > > > messages than before: > > > > > > ata1: link resume succeeded after 1 retries > > > ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > > > +ata1.00: qc timeout (cmd 0x2f) > > > +ata1.00: Read log page 0x00 failed, Emask 0x4 > > > +ata1.00: ATA Identify Device Log not supported > > > +ata1.00: failed to set xfermode (err_mask=0x40) > > > ata1: link resume succeeded after 1 retries > > > ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > > > +ata1.00: ATA Identify Device Log not supported > > > +ata1.00: ATA Identify Device Log not supported > > > ata1.00: configured for UDMA/133 > > > > > > I guess this is expected? > > > > Nope, it is not. The problem is actually not the concurrent positioning log, or > > any other log, being supported or not. > > > > Notice the qc timeout ? On device scan after coming out of sleep, or even simply > > doing a rmmod ahci+modprobe ahci, the read log commands issued during device > > revalidate timeout fairly easily as they are issued while the drive is not > > necessarilly fully restarted yet. These errors happen fairly easily due to the > > command timeout setting in libata being too short, I think, for the "restart" > > case. On a clean boot, they do not happen as longer timeouts are used in that case. > > > > I identified this problem recently while testing stuff: I was doing rmmod of ata > > modules and then modprobe of newly compiled modules for tests and noticed these > > timeouts. Increasing the timeout values, they disappear. I am however still > > scratching my head about the best way to address this. Still digging about this > > to first make sure this is really about timeouts being set too short. > > There's indeed something timing-related going on. Sometimes I get > during resume (s2idle or s2ram): > > ata1.00: qc timeout (cmd 0x2f) > ata1.00: Read log page 0x00 failed, Emask 0x4 > ata1.00: ATA Identify Device Log not supported > ata1.00: failed to set xfermode (err_mask=0x40) > ata1.00: limiting speed to UDMA/133:PIO3 > ata1: link resume succeeded after 1 retries > ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > ata1.00: NODEV after polling detection > ata1.00: revalidation failed (errno=-2) > ata1.00: disabled > ata1: link resume succeeded after 1 retries > ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > sd 0:0:0:0: [sda] Start/Stop Unit failed: Result: hostbyte=0x04 > driverbyte=DRIVER_OK > sd 0:0:0:0: [sda] Read Capacity(16) failed: Result: hostbyte=0x04 > driverbyte=DRIVER_OK > sd 0:0:0:0: [sda] Sense not available. > sd 0:0:0:0: [sda] Read Capacity(10) failed: Result: hostbyte=0x04 > driverbyte=DRIVER_OK > sd 0:0:0:0: [sda] Sense not available. > sd 0:0:0:0: [sda] 0 512-byte logical blocks: (0 B/0 B) > sda: detected capacity change from 320173056 to 0 > > after which the drive is no longer functional... Geert, Could you try with the following patch added to see if the problem goes away ? diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index bf9c4b6c5c3d..e53f4ea71d38 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -93,6 +93,12 @@ static const unsigned long ata_eh_identify_timeouts[] = { ULONG_MAX, }; +static const unsigned long ata_eh_revalidate_timeouts[] = { + 15000, /* Some drives are slow to read log pages when waking-up */ + 15000, /* combined time till here is enough even for media access */ + ULONG_MAX, +}; + static const unsigned long ata_eh_flush_timeouts[] = { 15000, /* be generous with flush */ 15000, /* ditto */ @@ -129,16 +135,17 @@ static const struct ata_eh_cmd_timeout_ent ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { { .commands = CMDS(ATA_CMD_ID_ATA, ATA_CMD_ID_ATAPI), .timeouts = ata_eh_identify_timeouts, }, - { .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, ATA_CMD_READ_NATIVE_MAX_EXT), - .timeouts = ata_eh_other_timeouts, }, - { .commands = CMDS(ATA_CMD_SET_MAX, ATA_CMD_SET_MAX_EXT), - .timeouts = ata_eh_other_timeouts, }, - { .commands = CMDS(ATA_CMD_SET_FEATURES), - .timeouts = ata_eh_other_timeouts, }, - { .commands = CMDS(ATA_CMD_INIT_DEV_PARAMS), - .timeouts = ata_eh_other_timeouts, }, + { .commands = CMDS(ATA_CMD_READ_LOG_EXT, ATA_CMD_READ_LOG_DMA_EXT), + .timeouts = ata_eh_revalidate_timeouts, }, { .commands = CMDS(ATA_CMD_FLUSH, ATA_CMD_FLUSH_EXT), .timeouts = ata_eh_flush_timeouts }, + { .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, \ + ATA_CMD_READ_NATIVE_MAX_EXT, \ + ATA_CMD_SET_MAX, \ + ATA_CMD_SET_MAX_EXT, \ + ATA_CMD_SET_FEATURES, \ + ATA_CMD_INIT_DEV_PARAMS), + .timeouts = ata_eh_other_timeouts, }, }; #undef CMDS diff --git a/include/linux/libata.h b/include/linux/libata.h index 236ec689056a..f2b12057ffcf 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -394,7 +394,7 @@ enum { /* This should match the actual table size of * ata_eh_cmd_timeout_table in libata-eh.c. */ - ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 6, + ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 4, /* Horkage types. May be set by libata or controller on drives (some horkage may be drive/controller pair dependent */ On my test box, I can reliably generate the same qc timeout errors you are seeing by doing: rmmod sd_mod ahci libahci libata modprobe ahci The first command will hard reset the drives (causing them to "reboot"). When the second command starts, revalidate is executed with the drives slow to respond to read log commands. The patch adds an auto timeout for read log commands, to set the timeout to 15s instead of the default 5s. With that, all timeout errors disappear. Note that these timeout numbers are totally arbitrary... > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like that. > -- Linus Torvalds
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index eed65311b5d1..75f1a6cd6621 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2459,18 +2459,70 @@ static void ata_dev_config_devslp(struct ata_device *dev) } } +static void ata_dev_config_cpr(struct ata_device *dev) +{ + unsigned int err_mask; + size_t buf_len; + int i, nr_cpr = 0; + struct ata_cpr_log *cpr_log = NULL; + u8 *desc, *buf = NULL; + + if (!ata_identify_page_supported(dev, + ATA_LOG_CONCURRENT_POSITIONING_RANGES)) + goto out; + + /* + * Read IDENTIFY DEVICE data log, page 0x47 + * (concurrent positioning ranges). We can have at most 255 32B range + * descriptors plus a 64B header. + */ + buf_len = (64 + 255 * 32 + 511) & ~511; + buf = kzalloc(buf_len, GFP_KERNEL); + if (!buf) + goto out; + + err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, + ATA_LOG_CONCURRENT_POSITIONING_RANGES, + buf, buf_len >> 9); + if (err_mask) + goto out; + + nr_cpr = buf[0]; + if (!nr_cpr) + goto out; + + cpr_log = kzalloc(struct_size(cpr_log, cpr, nr_cpr), GFP_KERNEL); + if (!cpr_log) + goto out; + + cpr_log->nr_cpr = nr_cpr; + desc = &buf[64]; + for (i = 0; i < nr_cpr; i++, desc += 32) { + cpr_log->cpr[i].num = desc[0]; + cpr_log->cpr[i].num_storage_elements = desc[1]; + cpr_log->cpr[i].start_lba = get_unaligned_le64(&desc[8]); + cpr_log->cpr[i].num_lbas = get_unaligned_le64(&desc[16]); + } + +out: + swap(dev->cpr_log, cpr_log); + kfree(cpr_log); + kfree(buf); +} + static void ata_dev_print_features(struct ata_device *dev) { if (!(dev->flags & ATA_DFLAG_FEATURES_MASK)) return; ata_dev_info(dev, - "Features:%s%s%s%s%s\n", + "Features:%s%s%s%s%s%s\n", dev->flags & ATA_DFLAG_TRUSTED ? " Trust" : "", dev->flags & ATA_DFLAG_DA ? " Dev-Attention" : "", dev->flags & ATA_DFLAG_DEVSLP ? " Dev-Sleep" : "", dev->flags & ATA_DFLAG_NCQ_SEND_RECV ? " NCQ-sndrcv" : "", - dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : ""); + dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : "", + dev->cpr_log ? " CPR" : ""); } /** @@ -2634,6 +2686,7 @@ int ata_dev_configure(struct ata_device *dev) ata_dev_config_sense_reporting(dev); ata_dev_config_zac(dev); ata_dev_config_trusted(dev); + ata_dev_config_cpr(dev); dev->cdb_len = 32; if (ata_msg_drv(ap) && print_info) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1fb4611f7eeb..15a279f773c7 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1895,7 +1895,7 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) */ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf) { - int num_pages; + int i, num_pages = 0; static const u8 pages[] = { 0x00, /* page 0x00, this page */ 0x80, /* page 0x80, unit serial no page */ @@ -1905,13 +1905,17 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf) 0xb1, /* page 0xb1, block device characteristics page */ 0xb2, /* page 0xb2, thin provisioning page */ 0xb6, /* page 0xb6, zoned block device characteristics */ + 0xb9, /* page 0xb9, concurrent positioning ranges */ }; - num_pages = sizeof(pages); - if (!(args->dev->flags & ATA_DFLAG_ZAC)) - num_pages--; + for (i = 0; i < sizeof(pages); i++) { + if (pages[i] == 0xb6 && + !(args->dev->flags & ATA_DFLAG_ZAC)) + continue; + rbuf[num_pages + 4] = pages[i]; + num_pages++; + } rbuf[3] = num_pages; /* number of supported VPD pages */ - memcpy(rbuf + 4, pages, num_pages); return 0; } @@ -2121,6 +2125,26 @@ static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf) return 0; } +static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf) +{ + struct ata_cpr_log *cpr_log = args->dev->cpr_log; + u8 *desc = &rbuf[64]; + int i; + + /* 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[3]); + + for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) { + desc[0] = cpr_log->cpr[i].num; + desc[1] = cpr_log->cpr[i].num_storage_elements; + put_unaligned_be64(cpr_log->cpr[i].start_lba, &desc[8]); + put_unaligned_be64(cpr_log->cpr[i].num_lbas, &desc[16]); + } + + return 0; +} + /** * modecpy - Prepare response for MODE SENSE * @dest: output buffer @@ -4120,11 +4144,17 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); break; case 0xb6: - if (dev->flags & ATA_DFLAG_ZAC) { + if (dev->flags & ATA_DFLAG_ZAC) ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6); - break; - } - fallthrough; + 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; diff --git a/include/linux/ata.h b/include/linux/ata.h index 1b44f40c7700..199e47e97d64 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -329,6 +329,7 @@ enum { ATA_LOG_SECURITY = 0x06, ATA_LOG_SATA_SETTINGS = 0x08, ATA_LOG_ZONED_INFORMATION = 0x09, + ATA_LOG_CONCURRENT_POSITIONING_RANGES = 0x47, /* Identify device SATA settings log:*/ ATA_LOG_DEVSLP_OFFSET = 0x30, diff --git a/include/linux/libata.h b/include/linux/libata.h index c0c64f03e107..236ec689056a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -676,6 +676,18 @@ struct ata_ering { struct ata_ering_entry ring[ATA_ERING_SIZE]; }; +struct ata_cpr { + u8 num; + u8 num_storage_elements; + u64 start_lba; + u64 num_lbas; +}; + +struct ata_cpr_log { + u8 nr_cpr; + struct ata_cpr cpr[]; +}; + struct ata_device { struct ata_link *link; unsigned int devno; /* 0 or 1 */ @@ -735,6 +747,9 @@ struct ata_device { u32 zac_zones_optimal_nonseq; u32 zac_zones_max_open; + /* Concurrent positioning ranges */ + struct ata_cpr_log *cpr_log; + /* error history */ int spdn_cnt; /* ering is CLEAR_END, read comment above CLEAR_END */