Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Gwendal Grignou and committed by
Jeff Garzik
d9027470 f6f94e2a

+987 -40
+99
Documentation/ABI/testing/sysfs-ata
··· 1 + What: /sys/class/ata_... 2 + Date: August 2008 3 + Contact: Gwendal Grignou<gwendal@google.com> 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.
+1 -1
drivers/ata/Makefile
··· 99 99 # Should be last libata driver 100 100 obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o 101 101 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 103 103 libata-$(CONFIG_ATA_SFF) += libata-sff.o 104 104 libata-$(CONFIG_SATA_PMP) += libata-pmp.o 105 105 libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
+43 -6
drivers/ata/libata-core.c
··· 68 68 #include <linux/ratelimit.h> 69 69 70 70 #include "libata.h" 71 - 71 + #include "libata-transport.h" 72 72 73 73 /* debounce timing parameters in msecs { interval, duration, timeout } */ 74 74 const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 }; ··· 1017 1017 return "<n/a>"; 1018 1018 } 1019 1019 1020 - static const char *sata_spd_string(unsigned int spd) 1020 + const char *sata_spd_string(unsigned int spd) 1021 1021 { 1022 1022 static const char * const spd_str[] = { 1023 1023 "1.5 Gbps", ··· 5517 5517 int i; 5518 5518 5519 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 5523 link->ap = ap; 5523 5524 link->pmp = pmp; ··· 5592 5591 ap = kzalloc(sizeof(*ap), GFP_KERNEL); 5593 5592 if (!ap) 5594 5593 return NULL; 5595 - 5594 + 5596 5595 ap->pflags |= ATA_PFLAG_INITIALIZING; 5597 5596 ap->lock = &host->lock; 5598 5597 ap->print_id = -1; ··· 6094 6093 for (i = 0; i < host->n_ports; i++) 6095 6094 host->ports[i]->print_id = ata_print_id++; 6096 6095 6096 + 6097 + /* Create associated sysfs transport objects */ 6098 + for (i = 0; i < host->n_ports; i++) { 6099 + rc = ata_tport_add(host->dev,host->ports[i]); 6100 + if (rc) { 6101 + goto err_tadd; 6102 + } 6103 + } 6104 + 6097 6105 rc = ata_scsi_add_hosts(host, sht); 6098 6106 if (rc) 6099 - return rc; 6107 + goto err_tadd; 6100 6108 6101 6109 /* associate with ACPI nodes */ 6102 6110 ata_acpi_associate(host); ··· 6146 6136 } 6147 6137 6148 6138 return 0; 6139 + 6140 + err_tadd: 6141 + while (--i >= 0) { 6142 + ata_tport_delete(host->ports[i]); 6143 + } 6144 + return rc; 6145 + 6149 6146 } 6150 6147 6151 6148 /** ··· 6243 6226 cancel_rearming_delayed_work(&ap->hotplug_task); 6244 6227 6245 6228 skip_eh: 6229 + if (ap->pmp_link) { 6230 + int i; 6231 + for (i = 0; i < SATA_PMP_MAX_PORTS; i++) 6232 + ata_tlink_delete(&ap->pmp_link[i]); 6233 + } 6234 + ata_tport_delete(ap); 6235 + 6246 6236 /* remove the associated SCSI host */ 6247 6237 scsi_remove_host(ap->scsi_host); 6248 6238 } ··· 6566 6542 6567 6543 static int __init ata_init(void) 6568 6544 { 6569 - int rc = -ENOMEM; 6545 + int rc; 6570 6546 6571 6547 ata_parse_force_param(); 6572 6548 ··· 6576 6552 return rc; 6577 6553 } 6578 6554 6555 + libata_transport_init(); 6556 + ata_scsi_transport_template = ata_attach_transport(); 6557 + if (!ata_scsi_transport_template) { 6558 + ata_sff_exit(); 6559 + rc = -ENOMEM; 6560 + goto err_out; 6561 + } 6562 + 6579 6563 printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n"); 6580 6564 return 0; 6565 + 6566 + err_out: 6567 + return rc; 6581 6568 } 6582 6569 6583 6570 static void __exit ata_exit(void) 6584 6571 { 6572 + ata_release_transport(ata_scsi_transport_template); 6573 + libata_transport_exit(); 6585 6574 ata_sff_exit(); 6586 6575 kfree(ata_force_tbl); 6587 6576 }
+21 -14
drivers/ata/libata-eh.c
··· 57 57 /* error flags */ 58 58 ATA_EFLAG_IS_IO = (1 << 0), 59 59 ATA_EFLAG_DUBIOUS_XFER = (1 << 1), 60 + ATA_EFLAG_OLD_ER = (1 << 31), 60 61 61 62 /* error categories */ 62 63 ATA_ECAT_NONE = 0, ··· 397 396 return NULL; 398 397 } 399 398 400 - static void ata_ering_clear(struct ata_ering *ering) 401 - { 402 - memset(ering, 0, sizeof(*ering)); 403 - } 404 - 405 - static int ata_ering_map(struct ata_ering *ering, 406 - int (*map_fn)(struct ata_ering_entry *, void *), 407 - void *arg) 399 + int ata_ering_map(struct ata_ering *ering, 400 + int (*map_fn)(struct ata_ering_entry *, void *), 401 + void *arg) 408 402 { 409 403 int idx, rc = 0; 410 404 struct ata_ering_entry *ent; ··· 416 420 } while (idx != ering->cursor); 417 421 418 422 return rc; 423 + } 424 + 425 + int ata_ering_clear_cb(struct ata_ering_entry *ent, void *void_arg) 426 + { 427 + ent->eflags |= ATA_EFLAG_OLD_ER; 428 + return 0; 429 + } 430 + 431 + static void ata_ering_clear(struct ata_ering *ering) 432 + { 433 + ata_ering_map(ering, ata_ering_clear_cb, NULL); 419 434 } 420 435 421 436 static unsigned int ata_eh_dev_action(struct ata_device *dev) ··· 579 572 int nr_timedout = 0; 580 573 581 574 spin_lock_irqsave(ap->lock, flags); 582 - 575 + 583 576 /* This must occur under the ap->lock as we don't want 584 577 a polled recovery to race the real interrupt handler 585 - 578 + 586 579 The lost_interrupt handler checks for any completed but 587 580 non-notified command and completes much like an IRQ handler. 588 - 581 + 589 582 We then fall into the error recovery code which will treat 590 583 this as if normal completion won the race */ 591 584 592 585 if (ap->ops->lost_interrupt) 593 586 ap->ops->lost_interrupt(ap); 594 - 587 + 595 588 list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { 596 589 struct ata_queued_cmd *qc; 597 590 ··· 635 628 ap->eh_tries = ATA_EH_MAX_TRIES; 636 629 } else 637 630 spin_unlock_wait(ap->lock); 638 - 631 + 639 632 /* If we timed raced normal completion and there is nothing to 640 633 recover nr_timedout == 0 why exactly are we doing error recovery ? */ 641 634 ··· 1762 1755 struct speed_down_verdict_arg *arg = void_arg; 1763 1756 int cat; 1764 1757 1765 - if (ent->timestamp < arg->since) 1758 + if ((ent->eflags & ATA_EFLAG_OLD_ER) || (ent->timestamp < arg->since)) 1766 1759 return -1; 1767 1760 1768 1761 cat = ata_eh_categorize_error(ent->eflags, ent->err_mask,
+16 -2
drivers/ata/libata-pmp.c
··· 11 11 #include <linux/libata.h> 12 12 #include <linux/slab.h> 13 13 #include "libata.h" 14 + #include "libata-transport.h" 14 15 15 16 const struct ata_port_operations sata_pmp_port_ops = { 16 17 .inherits = &sata_port_ops, ··· 313 312 return rc; 314 313 } 315 314 316 - static int sata_pmp_init_links(struct ata_port *ap, int nr_ports) 315 + static int sata_pmp_init_links (struct ata_port *ap, int nr_ports) 317 316 { 318 317 struct ata_link *pmp_link = ap->pmp_link; 319 - int i; 318 + int i, err; 320 319 321 320 if (!pmp_link) { 322 321 pmp_link = kzalloc(sizeof(pmp_link[0]) * SATA_PMP_MAX_PORTS, ··· 328 327 ata_link_init(ap, &pmp_link[i], i); 329 328 330 329 ap->pmp_link = pmp_link; 330 + 331 + for (i = 0; i < SATA_PMP_MAX_PORTS; i++) { 332 + err = ata_tlink_add(&pmp_link[i]); 333 + if (err) { 334 + goto err_tlink; 335 + } 336 + } 331 337 } 332 338 333 339 for (i = 0; i < nr_ports; i++) { ··· 347 339 } 348 340 349 341 return 0; 342 + err_tlink: 343 + while (--i >= 0) 344 + ata_tlink_delete(&pmp_link[i]); 345 + kfree(pmp_link); 346 + ap->pmp_link = NULL; 347 + return err; 350 348 } 351 349 352 350 static void sata_pmp_quirks(struct ata_port *ap)
+4 -17
drivers/ata/libata-scsi.c
··· 51 51 #include <asm/unaligned.h> 52 52 53 53 #include "libata.h" 54 + #include "libata-transport.h" 54 55 55 56 #define SECTOR_SIZE 512 56 57 #define ATA_SCSI_RBUF_SIZE 4096 ··· 65 64 const struct scsi_device *scsidev); 66 65 static struct ata_device *ata_scsi_find_dev(struct ata_port *ap, 67 66 const struct scsi_device *scsidev); 68 - static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, 69 - unsigned int id, unsigned int lun); 70 - 71 67 72 68 #define RW_RECOVERY_MPAGE 0x1 73 69 #define RW_RECOVERY_MPAGE_LEN 12 ··· 103 105 0, 0, 0, 0, 0xff, 0xff, 104 106 0, 30 /* extended self test time, see 05-359r1 */ 105 107 }; 106 - 107 - /* 108 - * libata transport template. libata doesn't do real transport stuff. 109 - * It just needs the eh_timed_out hook. 110 - */ 111 - static struct scsi_transport_template ata_scsi_transport_template = { 112 - .eh_strategy_handler = ata_scsi_error, 113 - .eh_timed_out = ata_scsi_timed_out, 114 - .user_scan = ata_scsi_user_scan, 115 - }; 116 - 117 108 118 109 static const struct { 119 110 enum link_pm value; ··· 3321 3334 *(struct ata_port **)&shost->hostdata[0] = ap; 3322 3335 ap->scsi_host = shost; 3323 3336 3324 - shost->transportt = &ata_scsi_transport_template; 3337 + shost->transportt = ata_scsi_transport_template; 3325 3338 shost->unique_id = ap->print_id; 3326 3339 shost->max_id = 16; 3327 3340 shost->max_lun = 1; ··· 3603 3616 * RETURNS: 3604 3617 * Zero. 3605 3618 */ 3606 - static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, 3607 - unsigned int id, unsigned int lun) 3619 + int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, 3620 + unsigned int id, unsigned int lun) 3608 3621 { 3609 3622 struct ata_port *ap = ata_shost_to_port(shost); 3610 3623 unsigned long flags;
+773
drivers/ata/libata-transport.c
··· 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 + 42 + struct scsi_transport_template; 43 + struct scsi_transport_template *ata_scsi_transport_template; 44 + 45 + struct 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 */ 83 + static int ata_tdev_add(struct ata_device *dev); 84 + static 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) \ 95 + static ssize_t \ 96 + get_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) \ 114 + static ssize_t \ 115 + get_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 + 131 + static 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 + }; 146 + ata_bitfield_name_search(class, ata_class_names) 147 + 148 + 149 + static 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 + }; 165 + ata_bitfield_name_match(err, ata_err_names) 166 + 167 + static 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 + }; 196 + ata_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) \ 202 + static ssize_t \ 203 + show_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)) \ 213 + static DEVICE_ATTR(name, S_IRUGO, show_ata_port_##name, NULL) 214 + 215 + ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int); 216 + ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long); 217 + 218 + static DECLARE_TRANSPORT_CLASS(ata_port_class, 219 + "ata_port", NULL, NULL, NULL); 220 + 221 + static 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 + */ 233 + int ata_is_port(const struct device *dev) 234 + { 235 + return dev->release == ata_tport_release; 236 + } 237 + 238 + static 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 + */ 252 + void 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 + */ 274 + int 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) \ 317 + static ssize_t \ 318 + show_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) \ 328 + static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL) 329 + 330 + ata_link_linkspeed_attr(hw_sata_spd_limit); 331 + ata_link_linkspeed_attr(sata_spd_limit); 332 + ata_link_linkspeed_attr(sata_spd); 333 + 334 + 335 + static DECLARE_TRANSPORT_CLASS(ata_link_class, 336 + "ata_link", NULL, NULL, NULL); 337 + 338 + static 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 + */ 350 + int ata_is_link(const struct device *dev) 351 + { 352 + return dev->release == ata_tlink_release; 353 + } 354 + 355 + static 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 + */ 370 + void 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 + */ 394 + int 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) \ 443 + static ssize_t \ 444 + show_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) \ 454 + static DEVICE_ATTR(field, S_IRUGO, show_ata_dev_##field, NULL) 455 + 456 + ata_dev_attr(class, class); 457 + ata_dev_attr(xfer, pio_mode); 458 + ata_dev_attr(xfer, dma_mode); 459 + ata_dev_attr(xfer, xfer_mode); 460 + 461 + 462 + #define ata_dev_show_simple(field, format_string, cast) \ 463 + static ssize_t \ 464 + show_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)) \ 474 + static DEVICE_ATTR(field, S_IRUGO, \ 475 + show_ata_dev_##field, NULL) 476 + 477 + ata_dev_simple_attr(spdn_cnt, "%d\n", int); 478 + 479 + struct ata_show_ering_arg { 480 + char* buf; 481 + int written; 482 + }; 483 + 484 + static 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 + 498 + static ssize_t 499 + show_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 + 510 + static DEVICE_ATTR(ering, S_IRUGO, show_ata_dev_ering, NULL); 511 + 512 + static ssize_t 513 + show_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 + 529 + static DEVICE_ATTR(id, S_IRUGO, show_ata_dev_id, NULL); 530 + 531 + static ssize_t 532 + show_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 + 550 + static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL); 551 + 552 + static DECLARE_TRANSPORT_CLASS(ata_dev_class, 553 + "ata_device", NULL, NULL, NULL); 554 + 555 + static 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 + */ 567 + int ata_is_ata_dev(const struct device *dev) 568 + { 569 + return dev->release == ata_tdev_release; 570 + } 571 + 572 + static 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 + */ 591 + static 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 + */ 603 + static 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 + */ 622 + static 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 + */ 673 + struct 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 + */ 733 + void 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 + 768 + void __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 + }
+18
drivers/ata/libata-transport.h
··· 1 + #ifndef _LIBATA_TRANSPORT_H 2 + #define _LIBATA_TRANSPORT_H 3 + 4 + 5 + extern struct scsi_transport_template *ata_scsi_transport_template; 6 + 7 + int ata_tlink_add(struct ata_link *link); 8 + void ata_tlink_delete(struct ata_link *link); 9 + 10 + int ata_tport_add(struct device *parent, struct ata_port *ap); 11 + void ata_tport_delete(struct ata_port *ap); 12 + 13 + struct scsi_transport_template *ata_attach_transport(void); 14 + void ata_release_transport(struct scsi_transport_template *t); 15 + 16 + __init int libata_transport_init(void); 17 + void __exit libata_transport_exit(void); 18 + #endif
+7
drivers/ata/libata.h
··· 102 102 extern struct ata_port *ata_port_alloc(struct ata_host *host); 103 103 extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy); 104 104 extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm); 105 + extern const char *sata_spd_string(unsigned int spd); 105 106 106 107 /* libata-acpi.c */ 107 108 #ifdef CONFIG_ATA_ACPI ··· 138 137 extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); 139 138 extern void ata_scsi_dev_rescan(struct work_struct *work); 140 139 extern int ata_bus_probe(struct ata_port *ap); 140 + extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, 141 + unsigned int id, unsigned int lun); 142 + 141 143 142 144 /* libata-eh.c */ 143 145 extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd); ··· 168 164 ata_postreset_fn_t postreset, 169 165 struct ata_link **r_failed_disk); 170 166 extern void ata_eh_finish(struct ata_port *ap); 167 + extern int ata_ering_map(struct ata_ering *ering, 168 + int (*map_fn)(struct ata_ering_entry *, void *), 169 + void *arg); 171 170 172 171 /* libata-pmp.c */ 173 172 #ifdef CONFIG_SATA_PMP
+5
include/linux/libata.h
··· 604 604 union acpi_object *gtf_cache; 605 605 unsigned int gtf_filter; 606 606 #endif 607 + struct device tdev; 607 608 /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */ 608 609 u64 n_sectors; /* size of device, if ATA */ 609 610 u64 n_native_sectors; /* native size, if ATA */ ··· 691 690 struct ata_port *ap; 692 691 int pmp; /* port multiplier port # */ 693 692 693 + struct device tdev; 694 694 unsigned int active_tag; /* active tag on this link */ 695 695 u32 sactive; /* active NCQ commands */ 696 696 ··· 709 707 710 708 struct ata_device device[ATA_MAX_DEVICES]; 711 709 }; 710 + #define ATA_LINK_CLEAR_BEGIN offsetof(struct ata_link, active_tag) 711 + #define ATA_LINK_CLEAR_END offsetof(struct ata_link, device[0]) 712 712 713 713 struct ata_port { 714 714 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */ ··· 756 752 struct ata_port_stats stats; 757 753 struct ata_host *host; 758 754 struct device *dev; 755 + struct device tdev; 759 756 760 757 struct mutex scsi_scan_mutex; 761 758 struct delayed_work hotplug_task;