Skip to content

Commit d902747

Browse files
Gwendal GrignouJeff Garzik
Gwendal Grignou
authored and
Jeff Garzik
committed
[libata] Add ATA transport class
This is a scheleton for libata transport class. All information is read only, exporting information from libata: - ata_port class: one per ATA port - ata_link class: one per ATA port or 15 for SATA Port Multiplier - ata_device class: up to 2 for PATA link, usually one for SATA. Signed-off-by: Gwendal Grignou <[email protected]> Reviewed-by: Grant Grundler <[email protected]> Signed-off-by: Jeff Garzik <[email protected]>
1 parent f6f94e2 commit d902747

File tree

10 files changed

+987
-40
lines changed

10 files changed

+987
-40
lines changed

Documentation/ABI/testing/sysfs-ata

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
What: /sys/class/ata_...
2+
Date: August 2008
3+
Contact: Gwendal Grignou<[email protected]>
4+
Description:
5+
6+
Provide a place in sysfs for storing the ATA topology of the system. This allows
7+
retrieving various information about ATA objects.
8+
9+
Files under /sys/class/ata_port
10+
-------------------------------
11+
12+
For each port, a directory ataX is created where X is the ata_port_id of
13+
the port. The device parent is the ata host device.
14+
15+
idle_irq (read)
16+
17+
Number of IRQ received by the port while idle [some ata HBA only].
18+
19+
nr_pmp_links (read)
20+
21+
If a SATA Port Multiplier (PM) is connected, number of link behind it.
22+
23+
Files under /sys/class/ata_link
24+
-------------------------------
25+
26+
Behind each port, there is a ata_link. If there is a SATA PM in the
27+
topology, 15 ata_link objects are created.
28+
29+
If a link is behind a port, the directory name is linkX, where X is
30+
ata_port_id of the port.
31+
If a link is behind a PM, its name is linkX.Y where X is ata_port_id
32+
of the parent port and Y the PM port.
33+
34+
hw_sata_spd_limit
35+
36+
Maximum speed supported by the connected SATA device.
37+
38+
sata_spd_limit
39+
40+
Maximum speed imposed by libata.
41+
42+
sata_spd
43+
44+
Current speed of the link [1.5, 3Gps,...].
45+
46+
Files under /sys/class/ata_device
47+
---------------------------------
48+
49+
Behind each link, up to two ata device are created.
50+
The name of the directory is devX[.Y].Z where:
51+
- X is ata_port_id of the port where the device is connected,
52+
- Y the port of the PM if any, and
53+
- Z the device id: for PATA, there is usually 2 devices [0,1],
54+
only 1 for SATA.
55+
56+
class
57+
Device class. Can be "ata" for disk, "atapi" for packet device,
58+
"pmp" for PM, or "none" if no device was found behind the link.
59+
60+
dma_mode
61+
62+
Transfer modes supported by the device when in DMA mode.
63+
Mostly used by PATA device.
64+
65+
pio_mode
66+
67+
Transfer modes supported by the device when in PIO mode.
68+
Mostly used by PATA device.
69+
70+
xfer_mode
71+
72+
Current transfer mode.
73+
74+
id
75+
76+
Cached result of IDENTIFY command, as described in ATA8 7.16 and 7.17.
77+
Only valid if the device is not a PM.
78+
79+
gscr
80+
81+
Cached result of the dump of PM GSCR register.
82+
Valid registers are:
83+
0: SATA_PMP_GSCR_PROD_ID,
84+
1: SATA_PMP_GSCR_REV,
85+
2: SATA_PMP_GSCR_PORT_INFO,
86+
32: SATA_PMP_GSCR_ERROR,
87+
33: SATA_PMP_GSCR_ERROR_EN,
88+
64: SATA_PMP_GSCR_FEAT,
89+
96: SATA_PMP_GSCR_FEAT_EN,
90+
130: SATA_PMP_GSCR_SII_GPIO
91+
Only valid if the device is a PM.
92+
93+
spdn_cnt
94+
95+
Number of time libata decided to lower the speed of link due to errors.
96+
97+
ering
98+
99+
Formatted output of the error ring of the device.

drivers/ata/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
9999
# Should be last libata driver
100100
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
101101

102-
libata-objs := libata-core.o libata-scsi.o libata-eh.o
102+
libata-objs := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
103103
libata-$(CONFIG_ATA_SFF) += libata-sff.o
104104
libata-$(CONFIG_SATA_PMP) += libata-pmp.o
105105
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o

drivers/ata/libata-core.c

+43-6
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
#include <linux/ratelimit.h>
6969

7070
#include "libata.h"
71-
71+
#include "libata-transport.h"
7272

7373
/* debounce timing parameters in msecs { interval, duration, timeout } */
7474
const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
@@ -1017,7 +1017,7 @@ const char *ata_mode_string(unsigned long xfer_mask)
10171017
return "<n/a>";
10181018
}
10191019

1020-
static const char *sata_spd_string(unsigned int spd)
1020+
const char *sata_spd_string(unsigned int spd)
10211021
{
10221022
static const char * const spd_str[] = {
10231023
"1.5 Gbps",
@@ -5517,7 +5517,8 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
55175517
int i;
55185518

55195519
/* clear everything except for devices */
5520-
memset(link, 0, offsetof(struct ata_link, device[0]));
5520+
memset((void *)link + ATA_LINK_CLEAR_BEGIN, 0,
5521+
ATA_LINK_CLEAR_END - ATA_LINK_CLEAR_BEGIN);
55215522

55225523
link->ap = ap;
55235524
link->pmp = pmp;
@@ -5591,7 +5592,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
55915592
ap = kzalloc(sizeof(*ap), GFP_KERNEL);
55925593
if (!ap)
55935594
return NULL;
5594-
5595+
55955596
ap->pflags |= ATA_PFLAG_INITIALIZING;
55965597
ap->lock = &host->lock;
55975598
ap->print_id = -1;
@@ -6093,9 +6094,18 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
60936094
for (i = 0; i < host->n_ports; i++)
60946095
host->ports[i]->print_id = ata_print_id++;
60956096

6097+
6098+
/* Create associated sysfs transport objects */
6099+
for (i = 0; i < host->n_ports; i++) {
6100+
rc = ata_tport_add(host->dev,host->ports[i]);
6101+
if (rc) {
6102+
goto err_tadd;
6103+
}
6104+
}
6105+
60966106
rc = ata_scsi_add_hosts(host, sht);
60976107
if (rc)
6098-
return rc;
6108+
goto err_tadd;
60996109

61006110
/* associate with ACPI nodes */
61016111
ata_acpi_associate(host);
@@ -6136,6 +6146,13 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
61366146
}
61376147

61386148
return 0;
6149+
6150+
err_tadd:
6151+
while (--i >= 0) {
6152+
ata_tport_delete(host->ports[i]);
6153+
}
6154+
return rc;
6155+
61396156
}
61406157

61416158
/**
@@ -6226,6 +6243,13 @@ static void ata_port_detach(struct ata_port *ap)
62266243
cancel_rearming_delayed_work(&ap->hotplug_task);
62276244

62286245
skip_eh:
6246+
if (ap->pmp_link) {
6247+
int i;
6248+
for (i = 0; i < SATA_PMP_MAX_PORTS; i++)
6249+
ata_tlink_delete(&ap->pmp_link[i]);
6250+
}
6251+
ata_tport_delete(ap);
6252+
62296253
/* remove the associated SCSI host */
62306254
scsi_remove_host(ap->scsi_host);
62316255
}
@@ -6542,7 +6566,7 @@ static void __init ata_parse_force_param(void)
65426566

65436567
static int __init ata_init(void)
65446568
{
6545-
int rc = -ENOMEM;
6569+
int rc;
65466570

65476571
ata_parse_force_param();
65486572

@@ -6552,12 +6576,25 @@ static int __init ata_init(void)
65526576
return rc;
65536577
}
65546578

6579+
libata_transport_init();
6580+
ata_scsi_transport_template = ata_attach_transport();
6581+
if (!ata_scsi_transport_template) {
6582+
ata_sff_exit();
6583+
rc = -ENOMEM;
6584+
goto err_out;
6585+
}
6586+
65556587
printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
65566588
return 0;
6589+
6590+
err_out:
6591+
return rc;
65576592
}
65586593

65596594
static void __exit ata_exit(void)
65606595
{
6596+
ata_release_transport(ata_scsi_transport_template);
6597+
libata_transport_exit();
65616598
ata_sff_exit();
65626599
kfree(ata_force_tbl);
65636600
}

drivers/ata/libata-eh.c

+21-14
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum {
5757
/* error flags */
5858
ATA_EFLAG_IS_IO = (1 << 0),
5959
ATA_EFLAG_DUBIOUS_XFER = (1 << 1),
60+
ATA_EFLAG_OLD_ER = (1 << 31),
6061

6162
/* error categories */
6263
ATA_ECAT_NONE = 0,
@@ -396,14 +397,9 @@ static struct ata_ering_entry *ata_ering_top(struct ata_ering *ering)
396397
return NULL;
397398
}
398399

399-
static void ata_ering_clear(struct ata_ering *ering)
400-
{
401-
memset(ering, 0, sizeof(*ering));
402-
}
403-
404-
static int ata_ering_map(struct ata_ering *ering,
405-
int (*map_fn)(struct ata_ering_entry *, void *),
406-
void *arg)
400+
int ata_ering_map(struct ata_ering *ering,
401+
int (*map_fn)(struct ata_ering_entry *, void *),
402+
void *arg)
407403
{
408404
int idx, rc = 0;
409405
struct ata_ering_entry *ent;
@@ -422,6 +418,17 @@ static int ata_ering_map(struct ata_ering *ering,
422418
return rc;
423419
}
424420

421+
int ata_ering_clear_cb(struct ata_ering_entry *ent, void *void_arg)
422+
{
423+
ent->eflags |= ATA_EFLAG_OLD_ER;
424+
return 0;
425+
}
426+
427+
static void ata_ering_clear(struct ata_ering *ering)
428+
{
429+
ata_ering_map(ering, ata_ering_clear_cb, NULL);
430+
}
431+
425432
static unsigned int ata_eh_dev_action(struct ata_device *dev)
426433
{
427434
struct ata_eh_context *ehc = &dev->link->eh_context;
@@ -572,19 +579,19 @@ void ata_scsi_error(struct Scsi_Host *host)
572579
int nr_timedout = 0;
573580

574581
spin_lock_irqsave(ap->lock, flags);
575-
582+
576583
/* This must occur under the ap->lock as we don't want
577584
a polled recovery to race the real interrupt handler
578-
585+
579586
The lost_interrupt handler checks for any completed but
580587
non-notified command and completes much like an IRQ handler.
581-
588+
582589
We then fall into the error recovery code which will treat
583590
this as if normal completion won the race */
584591

585592
if (ap->ops->lost_interrupt)
586593
ap->ops->lost_interrupt(ap);
587-
594+
588595
list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
589596
struct ata_queued_cmd *qc;
590597

@@ -628,7 +635,7 @@ void ata_scsi_error(struct Scsi_Host *host)
628635
ap->eh_tries = ATA_EH_MAX_TRIES;
629636
} else
630637
spin_unlock_wait(ap->lock);
631-
638+
632639
/* If we timed raced normal completion and there is nothing to
633640
recover nr_timedout == 0 why exactly are we doing error recovery ? */
634641

@@ -1755,7 +1762,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg)
17551762
struct speed_down_verdict_arg *arg = void_arg;
17561763
int cat;
17571764

1758-
if (ent->timestamp < arg->since)
1765+
if ((ent->eflags & ATA_EFLAG_OLD_ER) || (ent->timestamp < arg->since))
17591766
return -1;
17601767

17611768
cat = ata_eh_categorize_error(ent->eflags, ent->err_mask,

drivers/ata/libata-pmp.c

+16-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/libata.h>
1212
#include <linux/slab.h>
1313
#include "libata.h"
14+
#include "libata-transport.h"
1415

1516
const struct ata_port_operations sata_pmp_port_ops = {
1617
.inherits = &sata_port_ops,
@@ -312,10 +313,10 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
312313
return rc;
313314
}
314315

315-
static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
316+
static int sata_pmp_init_links (struct ata_port *ap, int nr_ports)
316317
{
317318
struct ata_link *pmp_link = ap->pmp_link;
318-
int i;
319+
int i, err;
319320

320321
if (!pmp_link) {
321322
pmp_link = kzalloc(sizeof(pmp_link[0]) * SATA_PMP_MAX_PORTS,
@@ -327,6 +328,13 @@ static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
327328
ata_link_init(ap, &pmp_link[i], i);
328329

329330
ap->pmp_link = pmp_link;
331+
332+
for (i = 0; i < SATA_PMP_MAX_PORTS; i++) {
333+
err = ata_tlink_add(&pmp_link[i]);
334+
if (err) {
335+
goto err_tlink;
336+
}
337+
}
330338
}
331339

332340
for (i = 0; i < nr_ports; i++) {
@@ -339,6 +347,12 @@ static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
339347
}
340348

341349
return 0;
350+
err_tlink:
351+
while (--i >= 0)
352+
ata_tlink_delete(&pmp_link[i]);
353+
kfree(pmp_link);
354+
ap->pmp_link = NULL;
355+
return err;
342356
}
343357

344358
static void sata_pmp_quirks(struct ata_port *ap)

0 commit comments

Comments
 (0)