aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@google.com>2010-05-25 15:31:38 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-10-21 20:21:03 -0400
commitd9027470b88631d0956ac37cdadfdeb9cdcf2c99 (patch)
treeb15273e88431ba734a24965dfc81132ac13bc8bd
parentf6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff)
[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 <gwendal@google.com> Reviewed-by: Grant Grundler <grundler@google.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--Documentation/ABI/testing/sysfs-ata99
-rw-r--r--drivers/ata/Makefile2
-rw-r--r--drivers/ata/libata-core.c49
-rw-r--r--drivers/ata/libata-eh.c35
-rw-r--r--drivers/ata/libata-pmp.c18
-rw-r--r--drivers/ata/libata-scsi.c21
-rw-r--r--drivers/ata/libata-transport.c773
-rw-r--r--drivers/ata/libata-transport.h18
-rw-r--r--drivers/ata/libata.h7
-rw-r--r--include/linux/libata.h5
10 files changed, 987 insertions, 40 deletions
diff --git a/Documentation/ABI/testing/sysfs-ata b/Documentation/ABI/testing/sysfs-ata
new file mode 100644
index 000000000000..0a932155cbba
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-ata
@@ -0,0 +1,99 @@
1What: /sys/class/ata_...
2Date: August 2008
3Contact: Gwendal Grignou<gwendal@google.com>
4Description:
5
6Provide a place in sysfs for storing the ATA topology of the system. This allows
7retrieving various information about ATA objects.
8
9Files 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
15idle_irq (read)
16
17 Number of IRQ received by the port while idle [some ata HBA only].
18
19nr_pmp_links (read)
20
21 If a SATA Port Multiplier (PM) is connected, number of link behind it.
22
23Files 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
34hw_sata_spd_limit
35
36 Maximum speed supported by the connected SATA device.
37
38sata_spd_limit
39
40 Maximum speed imposed by libata.
41
42sata_spd
43
44 Current speed of the link [1.5, 3Gps,...].
45
46Files 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
56class
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
60dma_mode
61
62 Transfer modes supported by the device when in DMA mode.
63 Mostly used by PATA device.
64
65pio_mode
66
67 Transfer modes supported by the device when in PIO mode.
68 Mostly used by PATA device.
69
70xfer_mode
71
72 Current transfer mode.
73
74id
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
79gscr
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
93spdn_cnt
94
95 Number of time libata decided to lower the speed of link due to errors.
96
97ering
98
99 Formatted output of the error ring of the device.
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index d5df04a395ca..ccd461bb5ee4 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -99,7 +99,7 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
99# Should be last libata driver 99# Should be last libata driver
100obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o 100obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
101 101
102libata-objs := libata-core.o libata-scsi.o libata-eh.o 102libata-objs := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
103libata-$(CONFIG_ATA_SFF) += libata-sff.o 103libata-$(CONFIG_ATA_SFF) += libata-sff.o
104libata-$(CONFIG_SATA_PMP) += libata-pmp.o 104libata-$(CONFIG_SATA_PMP) += libata-pmp.o
105libata-$(CONFIG_ATA_ACPI) += libata-acpi.o 105libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 932eaee50245..4012b33e8b8a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -68,7 +68,7 @@
68#include <linux/ratelimit.h> 68#include <linux/ratelimit.h>
69 69
70#include "libata.h" 70#include "libata.h"
71 71#include "libata-transport.h"
72 72
73/* debounce timing parameters in msecs { interval, duration, timeout } */ 73/* debounce timing parameters in msecs { interval, duration, timeout } */
74const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; 74const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
@@ -1017,7 +1017,7 @@ const char *ata_mode_string(unsigned long xfer_mask)
1017 return "<n/a>"; 1017 return "<n/a>";
1018} 1018}
1019 1019
1020static const char *sata_spd_string(unsigned int spd) 1020const char *sata_spd_string(unsigned int spd)
1021{ 1021{
1022 static const char * const spd_str[] = { 1022 static const char * const spd_str[] = {
1023 "1.5 Gbps", 1023 "1.5 Gbps",
@@ -5517,7 +5517,8 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
5517 int i; 5517 int i;
5518 5518
5519 /* clear everything except for devices */ 5519 /* 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);
5521 5522
5522 link->ap = ap; 5523 link->ap = ap;
5523 link->pmp = pmp; 5524 link->pmp = pmp;
@@ -5591,7 +5592,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
5591 ap = kzalloc(sizeof(*ap), GFP_KERNEL); 5592 ap = kzalloc(sizeof(*ap), GFP_KERNEL);
5592 if (!ap) 5593 if (!ap)
5593 return NULL; 5594 return NULL;
5594 5595
5595 ap->pflags |= ATA_PFLAG_INITIALIZING; 5596 ap->pflags |= ATA_PFLAG_INITIALIZING;
5596 ap->lock = &host->lock; 5597 ap->lock = &host->lock;
5597 ap->print_id = -1; 5598 ap->print_id = -1;
@@ -6093,9 +6094,18 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
6093 for (i = 0; i < host->n_ports; i++) 6094 for (i = 0; i < host->n_ports; i++)
6094 host->ports[i]->print_id = ata_print_id++; 6095 host->ports[i]->print_id = ata_print_id++;
6095 6096
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
6096 rc = ata_scsi_add_hosts(host, sht); 6106 rc = ata_scsi_add_hosts(host, sht);
6097 if (rc) 6107 if (rc)
6098 return rc; 6108 goto err_tadd;
6099 6109
6100 /* associate with ACPI nodes */ 6110 /* associate with ACPI nodes */
6101 ata_acpi_associate(host); 6111 ata_acpi_associate(host);
@@ -6136,6 +6146,13 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
6136 } 6146 }
6137 6147
6138 return 0; 6148 return 0;
6149
6150 err_tadd:
6151 while (--i >= 0) {
6152 ata_tport_delete(host->ports[i]);
6153 }
6154 return rc;
6155
6139} 6156}
6140 6157
6141/** 6158/**
@@ -6226,6 +6243,13 @@ static void ata_port_detach(struct ata_port *ap)
6226 cancel_rearming_delayed_work(&ap->hotplug_task); 6243 cancel_rearming_delayed_work(&ap->hotplug_task);
6227 6244
6228 skip_eh: 6245 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
6229 /* remove the associated SCSI host */ 6253 /* remove the associated SCSI host */
6230 scsi_remove_host(ap->scsi_host); 6254 scsi_remove_host(ap->scsi_host);
6231} 6255}
@@ -6542,7 +6566,7 @@ static void __init ata_parse_force_param(void)
6542 6566
6543static int __init ata_init(void) 6567static int __init ata_init(void)
6544{ 6568{
6545 int rc = -ENOMEM; 6569 int rc;
6546 6570
6547 ata_parse_force_param(); 6571 ata_parse_force_param();
6548 6572
@@ -6552,12 +6576,25 @@ static int __init ata_init(void)
6552 return rc; 6576 return rc;
6553 } 6577 }
6554 6578
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
6555 printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n"); 6587 printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
6556 return 0; 6588 return 0;
6589
6590err_out:
6591 return rc;
6557} 6592}
6558 6593
6559static void __exit ata_exit(void) 6594static void __exit ata_exit(void)
6560{ 6595{
6596 ata_release_transport(ata_scsi_transport_template);
6597 libata_transport_exit();
6561 ata_sff_exit(); 6598 ata_sff_exit();
6562 kfree(ata_force_tbl); 6599 kfree(ata_force_tbl);
6563} 6600}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index e48302eae55f..95838b382231 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -57,6 +57,7 @@ enum {
57 /* error flags */ 57 /* error flags */
58 ATA_EFLAG_IS_IO = (1 << 0), 58 ATA_EFLAG_IS_IO = (1 << 0),
59 ATA_EFLAG_DUBIOUS_XFER = (1 << 1), 59 ATA_EFLAG_DUBIOUS_XFER = (1 << 1),
60 ATA_EFLAG_OLD_ER = (1 << 31),
60 61
61 /* error categories */ 62 /* error categories */
62 ATA_ECAT_NONE = 0, 63 ATA_ECAT_NONE = 0,
@@ -396,14 +397,9 @@ static struct ata_ering_entry *ata_ering_top(struct ata_ering *ering)
396 return NULL; 397 return NULL;
397} 398}
398 399
399static void ata_ering_clear(struct ata_ering *ering) 400int ata_ering_map(struct ata_ering *ering,
400{ 401 int (*map_fn)(struct ata_ering_entry *, void *),
401 memset(ering, 0, sizeof(*ering)); 402 void *arg)
402}
403
404static int ata_ering_map(struct ata_ering *ering,
405 int (*map_fn)(struct ata_ering_entry *, void *),
406 void *arg)
407{ 403{
408 int idx, rc = 0; 404 int idx, rc = 0;
409 struct ata_ering_entry *ent; 405 struct ata_ering_entry *ent;
@@ -422,6 +418,17 @@ static int ata_ering_map(struct ata_ering *ering,
422 return rc; 418 return rc;
423} 419}
424 420
421int 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
427static void ata_ering_clear(struct ata_ering *ering)
428{
429 ata_ering_map(ering, ata_ering_clear_cb, NULL);
430}
431
425static unsigned int ata_eh_dev_action(struct ata_device *dev) 432static unsigned int ata_eh_dev_action(struct ata_device *dev)
426{ 433{
427 struct ata_eh_context *ehc = &dev->link->eh_context; 434 struct ata_eh_context *ehc = &dev->link->eh_context;
@@ -572,19 +579,19 @@ void ata_scsi_error(struct Scsi_Host *host)
572 int nr_timedout = 0; 579 int nr_timedout = 0;
573 580
574 spin_lock_irqsave(ap->lock, flags); 581 spin_lock_irqsave(ap->lock, flags);
575 582
576 /* This must occur under the ap->lock as we don't want 583 /* This must occur under the ap->lock as we don't want
577 a polled recovery to race the real interrupt handler 584 a polled recovery to race the real interrupt handler
578 585
579 The lost_interrupt handler checks for any completed but 586 The lost_interrupt handler checks for any completed but
580 non-notified command and completes much like an IRQ handler. 587 non-notified command and completes much like an IRQ handler.
581 588
582 We then fall into the error recovery code which will treat 589 We then fall into the error recovery code which will treat
583 this as if normal completion won the race */ 590 this as if normal completion won the race */
584 591
585 if (ap->ops->lost_interrupt) 592 if (ap->ops->lost_interrupt)
586 ap->ops->lost_interrupt(ap); 593 ap->ops->lost_interrupt(ap);
587 594
588 list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { 595 list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
589 struct ata_queued_cmd *qc; 596 struct ata_queued_cmd *qc;
590 597
@@ -628,7 +635,7 @@ void ata_scsi_error(struct Scsi_Host *host)
628 ap->eh_tries = ATA_EH_MAX_TRIES; 635 ap->eh_tries = ATA_EH_MAX_TRIES;
629 } else 636 } else
630 spin_unlock_wait(ap->lock); 637 spin_unlock_wait(ap->lock);
631 638
632 /* If we timed raced normal completion and there is nothing to 639 /* If we timed raced normal completion and there is nothing to
633 recover nr_timedout == 0 why exactly are we doing error recovery ? */ 640 recover nr_timedout == 0 why exactly are we doing error recovery ? */
634 641
@@ -1755,7 +1762,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg)
1755 struct speed_down_verdict_arg *arg = void_arg; 1762 struct speed_down_verdict_arg *arg = void_arg;
1756 int cat; 1763 int cat;
1757 1764
1758 if (ent->timestamp < arg->since) 1765 if ((ent->eflags & ATA_EFLAG_OLD_ER) || (ent->timestamp < arg->since))
1759 return -1; 1766 return -1;
1760 1767
1761 cat = ata_eh_categorize_error(ent->eflags, ent->err_mask, 1768 cat = ata_eh_categorize_error(ent->eflags, ent->err_mask,
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 224faabd7b7e..505470237d79 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -11,6 +11,7 @@
11#include <linux/libata.h> 11#include <linux/libata.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include "libata.h" 13#include "libata.h"
14#include "libata-transport.h"
14 15
15const struct ata_port_operations sata_pmp_port_ops = { 16const struct ata_port_operations sata_pmp_port_ops = {
16 .inherits = &sata_port_ops, 17 .inherits = &sata_port_ops,
@@ -312,10 +313,10 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info)
312 return rc; 313 return rc;
313} 314}
314 315
315static int sata_pmp_init_links(struct ata_port *ap, int nr_ports) 316static int sata_pmp_init_links (struct ata_port *ap, int nr_ports)
316{ 317{
317 struct ata_link *pmp_link = ap->pmp_link; 318 struct ata_link *pmp_link = ap->pmp_link;
318 int i; 319 int i, err;
319 320
320 if (!pmp_link) { 321 if (!pmp_link) {
321 pmp_link = kzalloc(sizeof(pmp_link[0]) * SATA_PMP_MAX_PORTS, 322 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)
327 ata_link_init(ap, &pmp_link[i], i); 328 ata_link_init(ap, &pmp_link[i], i);
328 329
329 ap->pmp_link = pmp_link; 330 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 }
330 } 338 }
331 339
332 for (i = 0; i < nr_ports; i++) { 340 for (i = 0; i < nr_ports; i++) {
@@ -339,6 +347,12 @@ static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
339 } 347 }
340 348
341 return 0; 349 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;
342} 356}
343 357
344static void sata_pmp_quirks(struct ata_port *ap) 358static void sata_pmp_quirks(struct ata_port *ap)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index a89172c100f5..c16f5c151735 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -51,6 +51,7 @@
51#include <asm/unaligned.h> 51#include <asm/unaligned.h>
52 52
53#include "libata.h" 53#include "libata.h"
54#include "libata-transport.h"
54 55
55#define SECTOR_SIZE 512 56#define SECTOR_SIZE 512
56#define ATA_SCSI_RBUF_SIZE 4096 57#define ATA_SCSI_RBUF_SIZE 4096
@@ -64,9 +65,6 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
64 const struct scsi_device *scsidev); 65 const struct scsi_device *scsidev);
65static struct ata_device *ata_scsi_find_dev(struct ata_port *ap, 66static struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
66 const struct scsi_device *scsidev); 67 const struct scsi_device *scsidev);
67static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
68 unsigned int id, unsigned int lun);
69
70 68
71#define RW_RECOVERY_MPAGE 0x1 69#define RW_RECOVERY_MPAGE 0x1
72#define RW_RECOVERY_MPAGE_LEN 12 70#define RW_RECOVERY_MPAGE_LEN 12
@@ -106,17 +104,6 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
106 0, 30 /* extended self test time, see 05-359r1 */ 104 0, 30 /* extended self test time, see 05-359r1 */
107}; 105};
108 106
109/*
110 * libata transport template. libata doesn't do real transport stuff.
111 * It just needs the eh_timed_out hook.
112 */
113static struct scsi_transport_template ata_scsi_transport_template = {
114 .eh_strategy_handler = ata_scsi_error,
115 .eh_timed_out = ata_scsi_timed_out,
116 .user_scan = ata_scsi_user_scan,
117};
118
119
120static const struct { 107static const struct {
121 enum link_pm value; 108 enum link_pm value;
122 const char *name; 109 const char *name;
@@ -3334,7 +3321,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
3334 *(struct ata_port **)&shost->hostdata[0] = ap; 3321 *(struct ata_port **)&shost->hostdata[0] = ap;
3335 ap->scsi_host = shost; 3322 ap->scsi_host = shost;
3336 3323
3337 shost->transportt = &ata_scsi_transport_template; 3324 shost->transportt = ata_scsi_transport_template;
3338 shost->unique_id = ap->print_id; 3325 shost->unique_id = ap->print_id;
3339 shost->max_id = 16; 3326 shost->max_id = 16;
3340 shost->max_lun = 1; 3327 shost->max_lun = 1;
@@ -3616,8 +3603,8 @@ void ata_scsi_hotplug(struct work_struct *work)
3616 * RETURNS: 3603 * RETURNS:
3617 * Zero. 3604 * Zero.
3618 */ 3605 */
3619static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, 3606int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
3620 unsigned int id, unsigned int lun) 3607 unsigned int id, unsigned int lun)
3621{ 3608{
3622 struct ata_port *ap = ata_shost_to_port(shost); 3609 struct ata_port *ap = ata_shost_to_port(shost);
3623 unsigned long flags; 3610 unsigned long flags;
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
new file mode 100644
index 000000000000..a80860f537e4
--- /dev/null
+++ b/drivers/ata/libata-transport.c
@@ -0,0 +1,773 @@
1/*
2 * Copyright 2008 ioogle, Inc. All rights reserved.
3 * Released under GPL v2.
4 *
5 * Libata transport class.
6 *
7 * The ATA transport class contains common code to deal with ATA HBAs,
8 * an approximated representation of ATA topologies in the driver model,
9 * and various sysfs attributes to expose these topologies and management
10 * interfaces to user-space.
11 *
12 * There are 3 objects defined in in this class:
13 * - ata_port
14 * - ata_link
15 * - ata_device
16 * Each port has a link object. Each link can have up to two devices for PATA
17 * and generally one for SATA.
18 * If there is SATA port multiplier [PMP], 15 additional ata_link object are
19 * created.
20 *
21 * These objects are created when the ata host is initialized and when a PMP is
22 * found. They are removed only when the HBA is removed, cleaned before the
23 * error handler runs.
24 */
25
26
27#include <linux/kernel.h>
28#include <linux/blkdev.h>
29#include <linux/spinlock.h>
30#include <scsi/scsi_transport.h>
31#include <linux/libata.h>
32#include <linux/hdreg.h>
33#include <linux/uaccess.h>
34
35#include "libata.h"
36#include "libata-transport.h"
37
38#define ATA_PORT_ATTRS 2
39#define ATA_LINK_ATTRS 3
40#define ATA_DEV_ATTRS 9
41
42struct scsi_transport_template;
43struct scsi_transport_template *ata_scsi_transport_template;
44
45struct ata_internal {
46 struct scsi_transport_template t;
47
48 struct device_attribute private_port_attrs[ATA_PORT_ATTRS];
49 struct device_attribute private_link_attrs[ATA_LINK_ATTRS];
50 struct device_attribute private_dev_attrs[ATA_DEV_ATTRS];
51
52 struct transport_container link_attr_cont;
53 struct transport_container dev_attr_cont;
54
55 /*
56 * The array of null terminated pointers to attributes
57 * needed by scsi_sysfs.c
58 */
59 struct device_attribute *link_attrs[ATA_LINK_ATTRS + 1];
60 struct device_attribute *port_attrs[ATA_PORT_ATTRS + 1];
61 struct device_attribute *dev_attrs[ATA_DEV_ATTRS + 1];
62};
63#define to_ata_internal(tmpl) container_of(tmpl, struct ata_internal, t)
64
65
66#define tdev_to_device(d) \
67 container_of((d), struct ata_device, tdev)
68#define transport_class_to_dev(dev) \
69 tdev_to_device((dev)->parent)
70
71#define tdev_to_link(d) \
72 container_of((d), struct ata_link, tdev)
73#define transport_class_to_link(dev) \
74 tdev_to_link((dev)->parent)
75
76#define tdev_to_port(d) \
77 container_of((d), struct ata_port, tdev)
78#define transport_class_to_port(dev) \
79 tdev_to_port((dev)->parent)
80
81
82/* Device objects are always created whit link objects */
83static int ata_tdev_add(struct ata_device *dev);
84static void ata_tdev_delete(struct ata_device *dev);
85
86
87/*
88 * Hack to allow attributes of the same name in different objects.
89 */
90#define ATA_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
91 struct device_attribute device_attr_##_prefix##_##_name = \
92 __ATTR(_name,_mode,_show,_store)
93
94#define ata_bitfield_name_match(title, table) \
95static ssize_t \
96get_ata_##title##_names(u32 table_key, char *buf) \
97{ \
98 char *prefix = ""; \
99 ssize_t len = 0; \
100 int i; \
101 \
102 for (i = 0; i < ARRAY_SIZE(table); i++) { \
103 if (table[i].value & table_key) { \
104 len += sprintf(buf + len, "%s%s", \
105 prefix, table[i].name); \
106 prefix = ", "; \
107 } \
108 } \
109 len += sprintf(buf + len, "\n"); \
110 return len; \
111}
112
113#define ata_bitfield_name_search(title, table) \
114static ssize_t \
115get_ata_##title##_names(u32 table_key, char *buf) \
116{ \
117 ssize_t len = 0; \
118 int i; \
119 \
120 for (i = 0; i < ARRAY_SIZE(table); i++) { \
121 if (table[i].value == table_key) { \
122 len += sprintf(buf + len, "%s", \
123 table[i].name); \
124 break; \
125 } \
126 } \
127 len += sprintf(buf + len, "\n"); \
128 return len; \
129}
130
131static struct {
132 u32 value;
133 char *name;
134} ata_class_names[] = {
135 { ATA_DEV_UNKNOWN, "unknown" },
136 { ATA_DEV_ATA, "ata" },
137 { ATA_DEV_ATA_UNSUP, "ata" },
138 { ATA_DEV_ATAPI, "atapi" },
139 { ATA_DEV_ATAPI_UNSUP, "atapi" },
140 { ATA_DEV_PMP, "pmp" },
141 { ATA_DEV_PMP_UNSUP, "pmp" },
142 { ATA_DEV_SEMB, "semb" },
143 { ATA_DEV_SEMB_UNSUP, "semb" },
144 { ATA_DEV_NONE, "none" }
145};
146ata_bitfield_name_search(class, ata_class_names)
147
148
149static struct {
150 u32 value;
151 char *name;
152} ata_err_names[] = {
153 { AC_ERR_DEV, "DeviceError" },
154 { AC_ERR_HSM, "HostStateMachineError" },
155 { AC_ERR_TIMEOUT, "Timeout" },
156 { AC_ERR_MEDIA, "MediaError" },
157 { AC_ERR_ATA_BUS, "BusError" },
158 { AC_ERR_HOST_BUS, "HostBusError" },
159 { AC_ERR_SYSTEM, "SystemError" },
160 { AC_ERR_INVALID, "InvalidArg" },
161 { AC_ERR_OTHER, "Unknown" },
162 { AC_ERR_NODEV_HINT, "NoDeviceHint" },
163 { AC_ERR_NCQ, "NCQError" }
164};
165ata_bitfield_name_match(err, ata_err_names)
166
167static struct {
168 u32 value;
169 char *name;
170} ata_xfer_names[] = {
171 { XFER_UDMA_7, "XFER_UDMA_7" },
172 { XFER_UDMA_6, "XFER_UDMA_6" },
173 { XFER_UDMA_5, "XFER_UDMA_5" },
174 { XFER_UDMA_4, "XFER_UDMA_4" },
175 { XFER_UDMA_3, "XFER_UDMA_3" },
176 { XFER_UDMA_2, "XFER_UDMA_2" },
177 { XFER_UDMA_1, "XFER_UDMA_1" },
178 { XFER_UDMA_0, "XFER_UDMA_0" },
179 { XFER_MW_DMA_4, "XFER_MW_DMA_4" },
180 { XFER_MW_DMA_3, "XFER_MW_DMA_3" },
181 { XFER_MW_DMA_2, "XFER_MW_DMA_2" },
182 { XFER_MW_DMA_1, "XFER_MW_DMA_1" },
183 { XFER_MW_DMA_0, "XFER_MW_DMA_0" },
184 { XFER_SW_DMA_2, "XFER_SW_DMA_2" },
185 { XFER_SW_DMA_1, "XFER_SW_DMA_1" },
186 { XFER_SW_DMA_0, "XFER_SW_DMA_0" },
187 { XFER_PIO_6, "XFER_PIO_6" },
188 { XFER_PIO_5, "XFER_PIO_5" },
189 { XFER_PIO_4, "XFER_PIO_4" },
190 { XFER_PIO_3, "XFER_PIO_3" },
191 { XFER_PIO_2, "XFER_PIO_2" },
192 { XFER_PIO_1, "XFER_PIO_1" },
193 { XFER_PIO_0, "XFER_PIO_0" },
194 { XFER_PIO_SLOW, "XFER_PIO_SLOW" }
195};
196ata_bitfield_name_match(xfer,ata_xfer_names)
197
198/*
199 * ATA Port attributes
200 */
201#define ata_port_show_simple(field, name, format_string, cast) \
202static ssize_t \
203show_ata_port_##name(struct device *dev, \
204 struct device_attribute *attr, char *buf) \
205{ \
206 struct ata_port *ap = transport_class_to_port(dev); \
207 \
208 return snprintf(buf, 20, format_string, cast ap->field); \
209}
210
211#define ata_port_simple_attr(field, name, format_string, type) \
212 ata_port_show_simple(field, name, format_string, (type)) \
213static DEVICE_ATTR(name, S_IRUGO, show_ata_port_##name, NULL)
214
215ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int);
216ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long);
217
218static DECLARE_TRANSPORT_CLASS(ata_port_class,
219 "ata_port", NULL, NULL, NULL);
220
221static void ata_tport_release(struct device *dev)
222{
223 put_device(dev->parent);
224}
225
226/**
227 * ata_is_port -- check if a struct device represents a ATA port
228 * @dev: device to check
229 *
230 * Returns:
231 * %1 if the device represents a ATA Port, %0 else
232 */
233int ata_is_port(const struct device *dev)
234{
235 return dev->release == ata_tport_release;
236}
237
238static int ata_tport_match(struct attribute_container *cont,
239 struct device *dev)
240{
241 if (!ata_is_port(dev))
242 return 0;
243 return &ata_scsi_transport_template->host_attrs.ac == cont;
244}
245
246/**
247 * ata_tport_delete -- remove ATA PORT
248 * @port: ATA PORT to remove
249 *
250 * Removes the specified ATA PORT. Remove the associated link as well.
251 */
252void ata_tport_delete(struct ata_port *ap)
253{
254 struct device *dev = &ap->tdev;
255
256 ata_tlink_delete(&ap->link);
257
258 transport_remove_device(dev);
259 device_del(dev);
260 transport_destroy_device(dev);
261 put_device(dev);
262}
263
264/** ata_tport_add - initialize a transport ATA port structure
265 *
266 * @parent: parent device
267 * @ap: existing ata_port structure
268 *
269 * Initialize a ATA port structure for sysfs. It will be added to the device
270 * tree below the device specified by @parent which could be a PCI device.
271 *
272 * Returns %0 on success
273 */
274int ata_tport_add(struct device *parent,
275 struct ata_port *ap)
276{
277 int error;
278 struct device *dev = &ap->tdev;
279
280 device_initialize(dev);
281
282 dev->parent = get_device(parent);
283 dev->release = ata_tport_release;
284 dev_set_name(dev, "ata%d", ap->print_id);
285 transport_setup_device(dev);
286 error = device_add(dev);
287 if (error) {
288 goto tport_err;
289 }
290
291 transport_add_device(dev);
292 transport_configure_device(dev);
293
294 error = ata_tlink_add(&ap->link);
295 if (error) {
296 goto tport_link_err;
297 }
298 return 0;
299
300 tport_link_err:
301 transport_remove_device(dev);
302 device_del(dev);
303
304 tport_err:
305 transport_destroy_device(dev);
306 put_device(dev);
307 return error;
308}
309
310
311/*
312 * ATA link attributes
313 */
314
315
316#define ata_link_show_linkspeed(field) \
317static ssize_t \
318show_ata_link_##field(struct device *dev, \
319 struct device_attribute *attr, char *buf) \
320{ \
321 struct ata_link *link = transport_class_to_link(dev); \
322 \
323 return sprintf(buf,"%s\n", sata_spd_string(fls(link->field))); \
324}
325
326#define ata_link_linkspeed_attr(field) \
327 ata_link_show_linkspeed(field) \
328static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL)
329
330ata_link_linkspeed_attr(hw_sata_spd_limit);
331ata_link_linkspeed_attr(sata_spd_limit);
332ata_link_linkspeed_attr(sata_spd);
333
334
335static DECLARE_TRANSPORT_CLASS(ata_link_class,
336 "ata_link", NULL, NULL, NULL);
337
338static void ata_tlink_release(struct device *dev)
339{
340 put_device(dev->parent);
341}
342
343/**
344 * ata_is_link -- check if a struct device represents a ATA link
345 * @dev: device to check
346 *
347 * Returns:
348 * %1 if the device represents a ATA link, %0 else
349 */
350int ata_is_link(const struct device *dev)
351{
352 return dev->release == ata_tlink_release;
353}
354
355static int ata_tlink_match(struct attribute_container *cont,
356 struct device *dev)
357{
358 struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
359 if (!ata_is_link(dev))
360 return 0;
361 return &i->link_attr_cont.ac == cont;
362}
363
364/**
365 * ata_tlink_delete -- remove ATA LINK
366 * @port: ATA LINK to remove
367 *
368 * Removes the specified ATA LINK. remove associated ATA device(s) as well.
369 */
370void ata_tlink_delete(struct ata_link *link)
371{
372 struct device *dev = &link->tdev;
373 struct ata_device *ata_dev;
374
375 ata_for_each_dev(ata_dev, link, ALL) {
376 ata_tdev_delete(ata_dev);
377 }
378
379 transport_remove_device(dev);
380 device_del(dev);
381 transport_destroy_device(dev);
382 put_device(dev);
383}
384
385/**
386 * ata_tlink_add -- initialize a transport ATA link structure
387 * @link: allocated ata_link structure.
388 *
389 * Initialize an ATA LINK structure for sysfs. It will be added in the
390 * device tree below the ATA PORT it belongs to.
391 *
392 * Returns %0 on success
393 */
394int ata_tlink_add(struct ata_link *link)
395{
396 struct device *dev = &link->tdev;
397 struct ata_port *ap = link->ap;
398 struct ata_device *ata_dev;
399 int error;
400
401 device_initialize(dev);
402 dev->parent = get_device(&ap->tdev);
403 dev->release = ata_tlink_release;
404 if (ata_is_host_link(link))
405 dev_set_name(dev, "link%d", ap->print_id);
406 else
407 dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp);
408
409 transport_setup_device(dev);
410
411 error = device_add(dev);
412 if (error) {
413 goto tlink_err;
414 }
415
416 transport_add_device(dev);
417 transport_configure_device(dev);
418
419 ata_for_each_dev(ata_dev, link, ALL) {
420 error = ata_tdev_add(ata_dev);
421 if (error) {
422 goto tlink_dev_err;
423 }
424 }
425 return 0;
426 tlink_dev_err:
427 while (--ata_dev >= link->device) {
428 ata_tdev_delete(ata_dev);
429 }
430 transport_remove_device(dev);
431 device_del(dev);
432 tlink_err:
433 transport_destroy_device(dev);
434 put_device(dev);
435 return error;
436}
437
438/*
439 * ATA device attributes
440 */
441
442#define ata_dev_show_class(title, field) \
443static ssize_t \
444show_ata_dev_##field(struct device *dev, \
445 struct device_attribute *attr, char *buf) \
446{ \
447 struct ata_device *ata_dev = transport_class_to_dev(dev); \
448 \
449 return get_ata_##title##_names(ata_dev->field, buf); \
450}
451
452#define ata_dev_attr(title, field) \
453 ata_dev_show_class(title, field) \
454static DEVICE_ATTR(field, S_IRUGO, show_ata_dev_##field, NULL)
455
456ata_dev_attr(class, class);
457ata_dev_attr(xfer, pio_mode);
458ata_dev_attr(xfer, dma_mode);
459ata_dev_attr(xfer, xfer_mode);
460
461
462#define ata_dev_show_simple(field, format_string, cast) \
463static ssize_t \
464show_ata_dev_##field(struct device *dev, \
465 struct device_attribute *attr, char *buf) \
466{ \
467 struct ata_device *ata_dev = transport_class_to_dev(dev); \
468 \
469 return snprintf(buf, 20, format_string, cast ata_dev->field); \
470}
471
472#define ata_dev_simple_attr(field, format_string, type) \
473 ata_dev_show_simple(field, format_string, (type)) \
474static DEVICE_ATTR(field, S_IRUGO, \
475 show_ata_dev_##field, NULL)
476
477ata_dev_simple_attr(spdn_cnt, "%d\n", int);
478
479struct ata_show_ering_arg {
480 char* buf;
481 int written;
482};
483
484static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
485{
486 struct ata_show_ering_arg* arg = void_arg;
487 struct timespec time;
488
489 jiffies_to_timespec(ent->timestamp,&time);
490 arg->written += sprintf(arg->buf + arg->written,
491 "[%5lu.%06lu]",
492 time.tv_sec, time.tv_nsec);
493 arg->written += get_ata_err_names(ent->err_mask,
494 arg->buf + arg->written);
495 return 0;
496}
497
498static ssize_t
499show_ata_dev_ering(struct device *dev,
500 struct device_attribute *attr, char *buf)
501{
502 struct ata_device *ata_dev = transport_class_to_dev(dev);
503 struct ata_show_ering_arg arg = { buf, 0 };
504
505 ata_ering_map(&ata_dev->ering, ata_show_ering, &arg);
506 return arg.written;
507}
508
509
510static DEVICE_ATTR(ering, S_IRUGO, show_ata_dev_ering, NULL);
511
512static ssize_t
513show_ata_dev_id(struct device *dev,
514 struct device_attribute *attr, char *buf)
515{
516 struct ata_device *ata_dev = transport_class_to_dev(dev);
517 int written = 0, i = 0;
518
519 if (ata_dev->class == ATA_DEV_PMP)
520 return 0;
521 for(i=0;i<ATA_ID_WORDS;i++) {
522 written += snprintf(buf+written, 20, "%04x%c",
523 ata_dev->id[i],
524 ((i+1) & 7) ? ' ' : '\n');
525 }
526 return written;
527}
528
529static DEVICE_ATTR(id, S_IRUGO, show_ata_dev_id, NULL);
530
531static ssize_t
532show_ata_dev_gscr(struct device *dev,
533 struct device_attribute *attr, char *buf)
534{
535 struct ata_device *ata_dev = transport_class_to_dev(dev);
536 int written = 0, i = 0;
537
538 if (ata_dev->class != ATA_DEV_PMP)
539 return 0;
540 for(i=0;i<SATA_PMP_GSCR_DWORDS;i++) {
541 written += snprintf(buf+written, 20, "%08x%c",
542 ata_dev->gscr[i],
543 ((i+1) & 3) ? ' ' : '\n');
544 }
545 if (SATA_PMP_GSCR_DWORDS & 3)
546 buf[written-1] = '\n';
547 return written;
548}
549
550static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL);
551
552static DECLARE_TRANSPORT_CLASS(ata_dev_class,
553 "ata_device", NULL, NULL, NULL);
554
555static void ata_tdev_release(struct device *dev)
556{
557 put_device(dev->parent);
558}
559
560/**
561 * ata_is_ata_dev -- check if a struct device represents a ATA device
562 * @dev: device to check
563 *
564 * Returns:
565 * %1 if the device represents a ATA device, %0 else
566 */
567int ata_is_ata_dev(const struct device *dev)
568{
569 return dev->release == ata_tdev_release;
570}
571
572static int ata_tdev_match(struct attribute_container *cont,
573 struct device *dev)
574{
575 struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
576 if (!ata_is_ata_dev(dev))
577 return 0;
578 return &i->dev_attr_cont.ac == cont;
579}
580
581/**
582 * ata_tdev_free -- free a ATA LINK
583 * @dev: ATA PHY to free
584 *
585 * Frees the specified ATA PHY.
586 *
587 * Note:
588 * This function must only be called on a PHY that has not
589 * successfully been added using ata_tdev_add().
590 */
591static void ata_tdev_free(struct ata_device *dev)
592{
593 transport_destroy_device(&dev->tdev);
594 put_device(&dev->tdev);
595}
596
597/**
598 * ata_tdev_delete -- remove ATA device
599 * @port: ATA PORT to remove
600 *
601 * Removes the specified ATA device.
602 */
603static void ata_tdev_delete(struct ata_device *ata_dev)
604{
605 struct device *dev = &ata_dev->tdev;
606
607 transport_remove_device(dev);
608 device_del(dev);
609 ata_tdev_free(ata_dev);
610}
611
612
613/**
614 * ata_tdev_add -- initialize a transport ATA device structure.
615 * @ata_dev: ata_dev structure.
616 *
617 * Initialize an ATA device structure for sysfs. It will be added in the
618 * device tree below the ATA LINK device it belongs to.
619 *
620 * Returns %0 on success
621 */
622static int ata_tdev_add(struct ata_device *ata_dev)
623{
624 struct device *dev = &ata_dev->tdev;
625 struct ata_link *link = ata_dev->link;
626 struct ata_port *ap = link->ap;
627 int error;
628
629 device_initialize(dev);
630 dev->parent = get_device(&link->tdev);
631 dev->release = ata_tdev_release;
632 if (ata_is_host_link(link))
633 dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno);
634 else
635 dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
636
637 transport_setup_device(dev);
638 error = device_add(dev);
639 if (error) {
640 ata_tdev_free(ata_dev);
641 return error;
642 }
643
644 transport_add_device(dev);
645 transport_configure_device(dev);
646 return 0;
647}
648
649
650/*
651 * Setup / Teardown code
652 */
653
654#define SETUP_TEMPLATE(attrb, field, perm, test) \
655 i->private_##attrb[count] = dev_attr_##field; \
656 i->private_##attrb[count].attr.mode = perm; \
657 i->attrb[count] = &i->private_##attrb[count]; \
658 if (test) \
659 count++
660
661#define SETUP_LINK_ATTRIBUTE(field) \
662 SETUP_TEMPLATE(link_attrs, field, S_IRUGO, 1)
663
664#define SETUP_PORT_ATTRIBUTE(field) \
665 SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
666
667#define SETUP_DEV_ATTRIBUTE(field) \
668 SETUP_TEMPLATE(dev_attrs, field, S_IRUGO, 1)
669
670/**
671 * ata_attach_transport -- instantiate ATA transport template
672 */
673struct scsi_transport_template *ata_attach_transport(void)
674{
675 struct ata_internal *i;
676 int count;
677
678 i = kzalloc(sizeof(struct ata_internal), GFP_KERNEL);
679 if (!i)
680 return NULL;
681
682 i->t.eh_strategy_handler = ata_scsi_error;
683 i->t.eh_timed_out = ata_scsi_timed_out;
684 i->t.user_scan = ata_scsi_user_scan;
685
686 i->t.host_attrs.ac.attrs = &i->port_attrs[0];
687 i->t.host_attrs.ac.class = &ata_port_class.class;
688 i->t.host_attrs.ac.match = ata_tport_match;
689 transport_container_register(&i->t.host_attrs);
690
691 i->link_attr_cont.ac.class = &ata_link_class.class;
692 i->link_attr_cont.ac.attrs = &i->link_attrs[0];
693 i->link_attr_cont.ac.match = ata_tlink_match;
694 transport_container_register(&i->link_attr_cont);
695
696 i->dev_attr_cont.ac.class = &ata_dev_class.class;
697 i->dev_attr_cont.ac.attrs = &i->dev_attrs[0];
698 i->dev_attr_cont.ac.match = ata_tdev_match;
699 transport_container_register(&i->dev_attr_cont);
700
701 count = 0;
702 SETUP_PORT_ATTRIBUTE(nr_pmp_links);
703 SETUP_PORT_ATTRIBUTE(idle_irq);
704 BUG_ON(count > ATA_PORT_ATTRS);
705 i->port_attrs[count] = NULL;
706
707 count = 0;
708 SETUP_LINK_ATTRIBUTE(hw_sata_spd_limit);
709 SETUP_LINK_ATTRIBUTE(sata_spd_limit);
710 SETUP_LINK_ATTRIBUTE(sata_spd);
711 BUG_ON(count > ATA_LINK_ATTRS);
712 i->link_attrs[count] = NULL;
713
714 count = 0;
715 SETUP_DEV_ATTRIBUTE(class);
716 SETUP_DEV_ATTRIBUTE(pio_mode);
717 SETUP_DEV_ATTRIBUTE(dma_mode);
718 SETUP_DEV_ATTRIBUTE(xfer_mode);
719 SETUP_DEV_ATTRIBUTE(spdn_cnt);
720 SETUP_DEV_ATTRIBUTE(ering);
721 SETUP_DEV_ATTRIBUTE(id);
722 SETUP_DEV_ATTRIBUTE(gscr);
723 BUG_ON(count > ATA_DEV_ATTRS);
724 i->dev_attrs[count] = NULL;
725
726 return &i->t;
727}
728
729/**
730 * ata_release_transport -- release ATA transport template instance
731 * @t: transport template instance
732 */
733void ata_release_transport(struct scsi_transport_template *t)
734{
735 struct ata_internal *i = to_ata_internal(t);
736
737 transport_container_unregister(&i->t.host_attrs);
738 transport_container_unregister(&i->link_attr_cont);
739 transport_container_unregister(&i->dev_attr_cont);
740
741 kfree(i);
742}
743
744__init int libata_transport_init(void)
745{
746 int error;
747
748 error = transport_class_register(&ata_link_class);
749 if (error)
750 goto out_unregister_transport;
751 error = transport_class_register(&ata_port_class);
752 if (error)
753 goto out_unregister_link;
754 error = transport_class_register(&ata_dev_class);
755 if (error)
756 goto out_unregister_port;
757 return 0;
758
759 out_unregister_port:
760 transport_class_unregister(&ata_port_class);
761 out_unregister_link:
762 transport_class_unregister(&ata_link_class);
763 out_unregister_transport:
764 return error;
765
766}
767
768void __exit libata_transport_exit(void)
769{
770 transport_class_unregister(&ata_link_class);
771 transport_class_unregister(&ata_port_class);
772 transport_class_unregister(&ata_dev_class);
773}
diff --git a/drivers/ata/libata-transport.h b/drivers/ata/libata-transport.h
new file mode 100644
index 000000000000..2820cf864f11
--- /dev/null
+++ b/drivers/ata/libata-transport.h
@@ -0,0 +1,18 @@
1#ifndef _LIBATA_TRANSPORT_H
2#define _LIBATA_TRANSPORT_H
3
4
5extern struct scsi_transport_template *ata_scsi_transport_template;
6
7int ata_tlink_add(struct ata_link *link);
8void ata_tlink_delete(struct ata_link *link);
9
10int ata_tport_add(struct device *parent, struct ata_port *ap);
11void ata_tport_delete(struct ata_port *ap);
12
13struct scsi_transport_template *ata_attach_transport(void);
14void ata_release_transport(struct scsi_transport_template *t);
15
16__init int libata_transport_init(void);
17void __exit libata_transport_exit(void);
18#endif
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 9ce1ecc63e39..142102b94df5 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -102,6 +102,7 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
102extern struct ata_port *ata_port_alloc(struct ata_host *host); 102extern struct ata_port *ata_port_alloc(struct ata_host *host);
103extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy); 103extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy);
104extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm); 104extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
105extern const char *sata_spd_string(unsigned int spd);
105 106
106/* libata-acpi.c */ 107/* libata-acpi.c */
107#ifdef CONFIG_ATA_ACPI 108#ifdef CONFIG_ATA_ACPI
@@ -137,6 +138,9 @@ extern void ata_scsi_hotplug(struct work_struct *work);
137extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); 138extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
138extern void ata_scsi_dev_rescan(struct work_struct *work); 139extern void ata_scsi_dev_rescan(struct work_struct *work);
139extern int ata_bus_probe(struct ata_port *ap); 140extern int ata_bus_probe(struct ata_port *ap);
141extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
142 unsigned int id, unsigned int lun);
143
140 144
141/* libata-eh.c */ 145/* libata-eh.c */
142extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd); 146extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
@@ -164,6 +168,9 @@ extern int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
164 ata_postreset_fn_t postreset, 168 ata_postreset_fn_t postreset,
165 struct ata_link **r_failed_disk); 169 struct ata_link **r_failed_disk);
166extern void ata_eh_finish(struct ata_port *ap); 170extern void ata_eh_finish(struct ata_port *ap);
171extern int ata_ering_map(struct ata_ering *ering,
172 int (*map_fn)(struct ata_ering_entry *, void *),
173 void *arg);
167 174
168/* libata-pmp.c */ 175/* libata-pmp.c */
169#ifdef CONFIG_SATA_PMP 176#ifdef CONFIG_SATA_PMP
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 45fb2967b66d..c50f66d4382c 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -604,6 +604,7 @@ struct ata_device {
604 union acpi_object *gtf_cache; 604 union acpi_object *gtf_cache;
605 unsigned int gtf_filter; 605 unsigned int gtf_filter;
606#endif 606#endif
607 struct device tdev;
607 /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */ 608 /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */
608 u64 n_sectors; /* size of device, if ATA */ 609 u64 n_sectors; /* size of device, if ATA */
609 u64 n_native_sectors; /* native size, if ATA */ 610 u64 n_native_sectors; /* native size, if ATA */
@@ -690,6 +691,7 @@ struct ata_link {
690 struct ata_port *ap; 691 struct ata_port *ap;
691 int pmp; /* port multiplier port # */ 692 int pmp; /* port multiplier port # */
692 693
694 struct device tdev;
693 unsigned int active_tag; /* active tag on this link */ 695 unsigned int active_tag; /* active tag on this link */
694 u32 sactive; /* active NCQ commands */ 696 u32 sactive; /* active NCQ commands */
695 697
@@ -707,6 +709,8 @@ struct ata_link {
707 709
708 struct ata_device device[ATA_MAX_DEVICES]; 710 struct ata_device device[ATA_MAX_DEVICES];
709}; 711};
712#define ATA_LINK_CLEAR_BEGIN offsetof(struct ata_link, active_tag)
713#define ATA_LINK_CLEAR_END offsetof(struct ata_link, device[0])
710 714
711struct ata_port { 715struct ata_port {
712 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */ 716 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */
@@ -752,6 +756,7 @@ struct ata_port {
752 struct ata_port_stats stats; 756 struct ata_port_stats stats;
753 struct ata_host *host; 757 struct ata_host *host;
754 struct device *dev; 758 struct device *dev;
759 struct device tdev;
755 760
756 struct mutex scsi_scan_mutex; 761 struct mutex scsi_scan_mutex;
757 struct delayed_work hotplug_task; 762 struct delayed_work hotplug_task;