linux/drivers/ata/libata-transport.c
<<
>>
Prefs
   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 <linux/slab.h>
  31#include <scsi/scsi_transport.h>
  32#include <linux/libata.h>
  33#include <linux/hdreg.h>
  34#include <linux/uaccess.h>
  35#include <linux/pm_runtime.h>
  36
  37#include "libata.h"
  38#include "libata-transport.h"
  39
  40#define ATA_PORT_ATTRS          3
  41#define ATA_LINK_ATTRS          3
  42#define ATA_DEV_ATTRS           9
  43
  44struct scsi_transport_template;
  45struct scsi_transport_template *ata_scsi_transport_template;
  46
  47struct ata_internal {
  48        struct scsi_transport_template t;
  49
  50        struct device_attribute private_port_attrs[ATA_PORT_ATTRS];
  51        struct device_attribute private_link_attrs[ATA_LINK_ATTRS];
  52        struct device_attribute private_dev_attrs[ATA_DEV_ATTRS];
  53
  54        struct transport_container link_attr_cont;
  55        struct transport_container dev_attr_cont;
  56
  57        /*
  58         * The array of null terminated pointers to attributes
  59         * needed by scsi_sysfs.c
  60         */
  61        struct device_attribute *link_attrs[ATA_LINK_ATTRS + 1];
  62        struct device_attribute *port_attrs[ATA_PORT_ATTRS + 1];
  63        struct device_attribute *dev_attrs[ATA_DEV_ATTRS + 1];
  64};
  65#define to_ata_internal(tmpl)   container_of(tmpl, struct ata_internal, t)
  66
  67
  68#define tdev_to_device(d)                                       \
  69        container_of((d), struct ata_device, tdev)
  70#define transport_class_to_dev(dev)                             \
  71        tdev_to_device((dev)->parent)
  72
  73#define tdev_to_link(d)                                         \
  74        container_of((d), struct ata_link, tdev)
  75#define transport_class_to_link(dev)                            \
  76        tdev_to_link((dev)->parent)
  77
  78#define tdev_to_port(d)                                         \
  79        container_of((d), struct ata_port, tdev)
  80#define transport_class_to_port(dev)                            \
  81        tdev_to_port((dev)->parent)
  82
  83
  84/* Device objects are always created whit link objects */
  85static int ata_tdev_add(struct ata_device *dev);
  86static void ata_tdev_delete(struct ata_device *dev);
  87
  88
  89/*
  90 * Hack to allow attributes of the same name in different objects.
  91 */
  92#define ATA_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
  93        struct device_attribute device_attr_##_prefix##_##_name = \
  94        __ATTR(_name,_mode,_show,_store)
  95
  96#define ata_bitfield_name_match(title, table)                   \
  97static ssize_t                                                  \
  98get_ata_##title##_names(u32 table_key, char *buf)               \
  99{                                                               \
 100        char *prefix = "";                                      \
 101        ssize_t len = 0;                                        \
 102        int i;                                                  \
 103                                                                \
 104        for (i = 0; i < ARRAY_SIZE(table); i++) {               \
 105                if (table[i].value & table_key) {               \
 106                        len += sprintf(buf + len, "%s%s",       \
 107                                prefix, table[i].name);         \
 108                        prefix = ", ";                          \
 109                }                                               \
 110        }                                                       \
 111        len += sprintf(buf + len, "\n");                        \
 112        return len;                                             \
 113}
 114
 115#define ata_bitfield_name_search(title, table)                  \
 116static ssize_t                                                  \
 117get_ata_##title##_names(u32 table_key, char *buf)               \
 118{                                                               \
 119        ssize_t len = 0;                                        \
 120        int i;                                                  \
 121                                                                \
 122        for (i = 0; i < ARRAY_SIZE(table); i++) {               \
 123                if (table[i].value == table_key) {              \
 124                        len += sprintf(buf + len, "%s",         \
 125                                table[i].name);                 \
 126                        break;                                  \
 127                }                                               \
 128        }                                                       \
 129        len += sprintf(buf + len, "\n");                        \
 130        return len;                                             \
 131}
 132
 133static struct {
 134        u32             value;
 135        char            *name;
 136} ata_class_names[] = {
 137        { ATA_DEV_UNKNOWN,              "unknown" },
 138        { ATA_DEV_ATA,                  "ata" },
 139        { ATA_DEV_ATA_UNSUP,            "ata" },
 140        { ATA_DEV_ATAPI,                "atapi" },
 141        { ATA_DEV_ATAPI_UNSUP,          "atapi" },
 142        { ATA_DEV_PMP,                  "pmp" },
 143        { ATA_DEV_PMP_UNSUP,            "pmp" },
 144        { ATA_DEV_SEMB,                 "semb" },
 145        { ATA_DEV_SEMB_UNSUP,           "semb" },
 146        { ATA_DEV_NONE,                 "none" }
 147};
 148ata_bitfield_name_search(class, ata_class_names)
 149
 150
 151static struct {
 152        u32             value;
 153        char            *name;
 154} ata_err_names[] = {
 155        { AC_ERR_DEV,                   "DeviceError" },
 156        { AC_ERR_HSM,                   "HostStateMachineError" },
 157        { AC_ERR_TIMEOUT,               "Timeout" },
 158        { AC_ERR_MEDIA,                 "MediaError" },
 159        { AC_ERR_ATA_BUS,               "BusError" },
 160        { AC_ERR_HOST_BUS,              "HostBusError" },
 161        { AC_ERR_SYSTEM,                "SystemError" },
 162        { AC_ERR_INVALID,               "InvalidArg" },
 163        { AC_ERR_OTHER,                 "Unknown" },
 164        { AC_ERR_NODEV_HINT,            "NoDeviceHint" },
 165        { AC_ERR_NCQ,                   "NCQError" }
 166};
 167ata_bitfield_name_match(err, ata_err_names)
 168
 169static struct {
 170        u32             value;
 171        char            *name;
 172} ata_xfer_names[] = {
 173        { XFER_UDMA_7,                  "XFER_UDMA_7" },
 174        { XFER_UDMA_6,                  "XFER_UDMA_6" },
 175        { XFER_UDMA_5,                  "XFER_UDMA_5" },
 176        { XFER_UDMA_4,                  "XFER_UDMA_4" },
 177        { XFER_UDMA_3,                  "XFER_UDMA_3" },
 178        { XFER_UDMA_2,                  "XFER_UDMA_2" },
 179        { XFER_UDMA_1,                  "XFER_UDMA_1" },
 180        { XFER_UDMA_0,                  "XFER_UDMA_0" },
 181        { XFER_MW_DMA_4,                "XFER_MW_DMA_4" },
 182        { XFER_MW_DMA_3,                "XFER_MW_DMA_3" },
 183        { XFER_MW_DMA_2,                "XFER_MW_DMA_2" },
 184        { XFER_MW_DMA_1,                "XFER_MW_DMA_1" },
 185        { XFER_MW_DMA_0,                "XFER_MW_DMA_0" },
 186        { XFER_SW_DMA_2,                "XFER_SW_DMA_2" },
 187        { XFER_SW_DMA_1,                "XFER_SW_DMA_1" },
 188        { XFER_SW_DMA_0,                "XFER_SW_DMA_0" },
 189        { XFER_PIO_6,                   "XFER_PIO_6" },
 190        { XFER_PIO_5,                   "XFER_PIO_5" },
 191        { XFER_PIO_4,                   "XFER_PIO_4" },
 192        { XFER_PIO_3,                   "XFER_PIO_3" },
 193        { XFER_PIO_2,                   "XFER_PIO_2" },
 194        { XFER_PIO_1,                   "XFER_PIO_1" },
 195        { XFER_PIO_0,                   "XFER_PIO_0" },
 196        { XFER_PIO_SLOW,                "XFER_PIO_SLOW" }
 197};
 198ata_bitfield_name_match(xfer,ata_xfer_names)
 199
 200/*
 201 * ATA Port attributes
 202 */
 203#define ata_port_show_simple(field, name, format_string, cast)          \
 204static ssize_t                                                          \
 205show_ata_port_##name(struct device *dev,                                \
 206                     struct device_attribute *attr, char *buf)          \
 207{                                                                       \
 208        struct ata_port *ap = transport_class_to_port(dev);             \
 209                                                                        \
 210        return snprintf(buf, 20, format_string, cast ap->field);        \
 211}
 212
 213#define ata_port_simple_attr(field, name, format_string, type)          \
 214        ata_port_show_simple(field, name, format_string, (type))        \
 215static DEVICE_ATTR(name, S_IRUGO, show_ata_port_##name, NULL)
 216
 217ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int);
 218ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long);
 219ata_port_simple_attr(local_port_no, port_no, "%u\n", unsigned int);
 220
 221static DECLARE_TRANSPORT_CLASS(ata_port_class,
 222                               "ata_port", NULL, NULL, NULL);
 223
 224static void ata_tport_release(struct device *dev)
 225{
 226        put_device(dev->parent);
 227}
 228
 229/**
 230 * ata_is_port --  check if a struct device represents a ATA port
 231 * @dev:        device to check
 232 *
 233 * Returns:
 234 *      %1 if the device represents a ATA Port, %0 else
 235 */
 236static int ata_is_port(const struct device *dev)
 237{
 238        return dev->release == ata_tport_release;
 239}
 240
 241static int ata_tport_match(struct attribute_container *cont,
 242                           struct device *dev)
 243{
 244        if (!ata_is_port(dev))
 245                return 0;
 246        return &ata_scsi_transport_template->host_attrs.ac == cont;
 247}
 248
 249/**
 250 * ata_tport_delete  --  remove ATA PORT
 251 * @port:       ATA PORT to remove
 252 *
 253 * Removes the specified ATA PORT.  Remove the associated link as well.
 254 */
 255void ata_tport_delete(struct ata_port *ap)
 256{
 257        struct device *dev = &ap->tdev;
 258
 259        ata_tlink_delete(&ap->link);
 260
 261        transport_remove_device(dev);
 262        device_del(dev);
 263        transport_destroy_device(dev);
 264        put_device(dev);
 265}
 266
 267/** ata_tport_add - initialize a transport ATA port structure
 268 *
 269 * @parent:     parent device
 270 * @ap:         existing ata_port structure
 271 *
 272 * Initialize a ATA port structure for sysfs.  It will be added to the device
 273 * tree below the device specified by @parent which could be a PCI device.
 274 *
 275 * Returns %0 on success
 276 */
 277int ata_tport_add(struct device *parent,
 278                  struct ata_port *ap)
 279{
 280        int error;
 281        struct device *dev = &ap->tdev;
 282
 283        device_initialize(dev);
 284        dev->type = &ata_port_type;
 285
 286        dev->parent = get_device(parent);
 287        dev->release = ata_tport_release;
 288        dev_set_name(dev, "ata%d", ap->print_id);
 289        transport_setup_device(dev);
 290        ata_acpi_bind_port(ap);
 291        error = device_add(dev);
 292        if (error) {
 293                goto tport_err;
 294        }
 295
 296        device_enable_async_suspend(dev);
 297        pm_runtime_set_active(dev);
 298        pm_runtime_enable(dev);
 299        pm_runtime_forbid(dev);
 300
 301        transport_add_device(dev);
 302        transport_configure_device(dev);
 303
 304        error = ata_tlink_add(&ap->link);
 305        if (error) {
 306                goto tport_link_err;
 307        }
 308        return 0;
 309
 310 tport_link_err:
 311        transport_remove_device(dev);
 312        device_del(dev);
 313
 314 tport_err:
 315        transport_destroy_device(dev);
 316        put_device(dev);
 317        return error;
 318}
 319
 320
 321/*
 322 * ATA link attributes
 323 */
 324
 325
 326#define ata_link_show_linkspeed(field)                                  \
 327static ssize_t                                                          \
 328show_ata_link_##field(struct device *dev,                               \
 329                      struct device_attribute *attr, char *buf)         \
 330{                                                                       \
 331        struct ata_link *link = transport_class_to_link(dev);           \
 332                                                                        \
 333        return sprintf(buf,"%s\n", sata_spd_string(fls(link->field)));  \
 334}
 335
 336#define ata_link_linkspeed_attr(field)                                  \
 337        ata_link_show_linkspeed(field)                                  \
 338static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL)
 339
 340ata_link_linkspeed_attr(hw_sata_spd_limit);
 341ata_link_linkspeed_attr(sata_spd_limit);
 342ata_link_linkspeed_attr(sata_spd);
 343
 344
 345static DECLARE_TRANSPORT_CLASS(ata_link_class,
 346                "ata_link", NULL, NULL, NULL);
 347
 348static void ata_tlink_release(struct device *dev)
 349{
 350        put_device(dev->parent);
 351}
 352
 353/**
 354 * ata_is_link --  check if a struct device represents a ATA link
 355 * @dev:        device to check
 356 *
 357 * Returns:
 358 *      %1 if the device represents a ATA link, %0 else
 359 */
 360static int ata_is_link(const struct device *dev)
 361{
 362        return dev->release == ata_tlink_release;
 363}
 364
 365static int ata_tlink_match(struct attribute_container *cont,
 366                           struct device *dev)
 367{
 368        struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
 369        if (!ata_is_link(dev))
 370                return 0;
 371        return &i->link_attr_cont.ac == cont;
 372}
 373
 374/**
 375 * ata_tlink_delete  --  remove ATA LINK
 376 * @port:       ATA LINK to remove
 377 *
 378 * Removes the specified ATA LINK.  remove associated ATA device(s) as well.
 379 */
 380void ata_tlink_delete(struct ata_link *link)
 381{
 382        struct device *dev = &link->tdev;
 383        struct ata_device *ata_dev;
 384
 385        ata_for_each_dev(ata_dev, link, ALL) {
 386                ata_tdev_delete(ata_dev);
 387        }
 388
 389        transport_remove_device(dev);
 390        device_del(dev);
 391        transport_destroy_device(dev);
 392        put_device(dev);
 393}
 394
 395/**
 396 * ata_tlink_add  --  initialize a transport ATA link structure
 397 * @link:       allocated ata_link structure.
 398 *
 399 * Initialize an ATA LINK structure for sysfs.  It will be added in the
 400 * device tree below the ATA PORT it belongs to.
 401 *
 402 * Returns %0 on success
 403 */
 404int ata_tlink_add(struct ata_link *link)
 405{
 406        struct device *dev = &link->tdev;
 407        struct ata_port *ap = link->ap;
 408        struct ata_device *ata_dev;
 409        int error;
 410
 411        device_initialize(dev);
 412        dev->parent = get_device(&ap->tdev);
 413        dev->release = ata_tlink_release;
 414        if (ata_is_host_link(link))
 415                dev_set_name(dev, "link%d", ap->print_id);
 416        else
 417                dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp);
 418
 419        transport_setup_device(dev);
 420
 421        error = device_add(dev);
 422        if (error) {
 423                goto tlink_err;
 424        }
 425
 426        transport_add_device(dev);
 427        transport_configure_device(dev);
 428
 429        ata_for_each_dev(ata_dev, link, ALL) {
 430                error = ata_tdev_add(ata_dev);
 431                if (error) {
 432                        goto tlink_dev_err;
 433                }
 434        }
 435        return 0;
 436  tlink_dev_err:
 437        while (--ata_dev >= link->device) {
 438                ata_tdev_delete(ata_dev);
 439        }
 440        transport_remove_device(dev);
 441        device_del(dev);
 442  tlink_err:
 443        transport_destroy_device(dev);
 444        put_device(dev);
 445        return error;
 446}
 447
 448/*
 449 * ATA device attributes
 450 */
 451
 452#define ata_dev_show_class(title, field)                                \
 453static ssize_t                                                          \
 454show_ata_dev_##field(struct device *dev,                                \
 455                     struct device_attribute *attr, char *buf)          \
 456{                                                                       \
 457        struct ata_device *ata_dev = transport_class_to_dev(dev);       \
 458                                                                        \
 459        return get_ata_##title##_names(ata_dev->field, buf);            \
 460}
 461
 462#define ata_dev_attr(title, field)                                      \
 463        ata_dev_show_class(title, field)                                \
 464static DEVICE_ATTR(field, S_IRUGO, show_ata_dev_##field, NULL)
 465
 466ata_dev_attr(class, class);
 467ata_dev_attr(xfer, pio_mode);
 468ata_dev_attr(xfer, dma_mode);
 469ata_dev_attr(xfer, xfer_mode);
 470
 471
 472#define ata_dev_show_simple(field, format_string, cast)         \
 473static ssize_t                                                          \
 474show_ata_dev_##field(struct device *dev,                                \
 475                     struct device_attribute *attr, char *buf)          \
 476{                                                                       \
 477        struct ata_device *ata_dev = transport_class_to_dev(dev);       \
 478                                                                        \
 479        return snprintf(buf, 20, format_string, cast ata_dev->field);   \
 480}
 481
 482#define ata_dev_simple_attr(field, format_string, type) \
 483        ata_dev_show_simple(field, format_string, (type))       \
 484static DEVICE_ATTR(field, S_IRUGO,                      \
 485                   show_ata_dev_##field, NULL)
 486
 487ata_dev_simple_attr(spdn_cnt, "%d\n", int);
 488
 489struct ata_show_ering_arg {
 490        char* buf;
 491        int written;
 492};
 493
 494static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
 495{
 496        struct ata_show_ering_arg* arg = void_arg;
 497        struct timespec time;
 498
 499        jiffies_to_timespec(ent->timestamp,&time);
 500        arg->written += sprintf(arg->buf + arg->written,
 501                               "[%5lu.%06lu]",
 502                               time.tv_sec, time.tv_nsec);
 503        arg->written += get_ata_err_names(ent->err_mask,
 504                                          arg->buf + arg->written);
 505        return 0;
 506}
 507
 508static ssize_t
 509show_ata_dev_ering(struct device *dev,
 510                   struct device_attribute *attr, char *buf)
 511{
 512        struct ata_device *ata_dev = transport_class_to_dev(dev);
 513        struct ata_show_ering_arg arg = { buf, 0 };
 514
 515        ata_ering_map(&ata_dev->ering, ata_show_ering, &arg);
 516        return arg.written;
 517}
 518
 519
 520static DEVICE_ATTR(ering, S_IRUGO, show_ata_dev_ering, NULL);
 521
 522static ssize_t
 523show_ata_dev_id(struct device *dev,
 524                struct device_attribute *attr, char *buf)
 525{
 526        struct ata_device *ata_dev = transport_class_to_dev(dev);
 527        int written = 0, i = 0;
 528
 529        if (ata_dev->class == ATA_DEV_PMP)
 530                return 0;
 531        for(i=0;i<ATA_ID_WORDS;i++)  {
 532                written += snprintf(buf+written, 20, "%04x%c",
 533                                    ata_dev->id[i],
 534                                    ((i+1) & 7) ? ' ' : '\n');
 535        }
 536        return written;
 537}
 538
 539static DEVICE_ATTR(id, S_IRUGO, show_ata_dev_id, NULL);
 540
 541static ssize_t
 542show_ata_dev_gscr(struct device *dev,
 543                  struct device_attribute *attr, char *buf)
 544{
 545        struct ata_device *ata_dev = transport_class_to_dev(dev);
 546        int written = 0, i = 0;
 547
 548        if (ata_dev->class != ATA_DEV_PMP)
 549                return 0;
 550        for(i=0;i<SATA_PMP_GSCR_DWORDS;i++)  {
 551                written += snprintf(buf+written, 20, "%08x%c",
 552                                    ata_dev->gscr[i],
 553                                    ((i+1) & 3) ? ' ' : '\n');
 554        }
 555        if (SATA_PMP_GSCR_DWORDS & 3)
 556                buf[written-1] = '\n';
 557        return written;
 558}
 559
 560static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL);
 561
 562static DECLARE_TRANSPORT_CLASS(ata_dev_class,
 563                               "ata_device", NULL, NULL, NULL);
 564
 565static void ata_tdev_release(struct device *dev)
 566{
 567        put_device(dev->parent);
 568}
 569
 570/**
 571 * ata_is_ata_dev  --  check if a struct device represents a ATA device
 572 * @dev:        device to check
 573 *
 574 * Returns:
 575 *      %1 if the device represents a ATA device, %0 else
 576 */
 577static int ata_is_ata_dev(const struct device *dev)
 578{
 579        return dev->release == ata_tdev_release;
 580}
 581
 582static int ata_tdev_match(struct attribute_container *cont,
 583                          struct device *dev)
 584{
 585        struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
 586        if (!ata_is_ata_dev(dev))
 587                return 0;
 588        return &i->dev_attr_cont.ac == cont;
 589}
 590
 591/**
 592 * ata_tdev_free  --  free a ATA LINK
 593 * @dev:        ATA PHY to free
 594 *
 595 * Frees the specified ATA PHY.
 596 *
 597 * Note:
 598 *   This function must only be called on a PHY that has not
 599 *   successfully been added using ata_tdev_add().
 600 */
 601static void ata_tdev_free(struct ata_device *dev)
 602{
 603        transport_destroy_device(&dev->tdev);
 604        put_device(&dev->tdev);
 605}
 606
 607/**
 608 * ata_tdev_delete  --  remove ATA device
 609 * @port:       ATA PORT to remove
 610 *
 611 * Removes the specified ATA device.
 612 */
 613static void ata_tdev_delete(struct ata_device *ata_dev)
 614{
 615        struct device *dev = &ata_dev->tdev;
 616
 617        transport_remove_device(dev);
 618        device_del(dev);
 619        ata_tdev_free(ata_dev);
 620}
 621
 622
 623/**
 624 * ata_tdev_add  --  initialize a transport ATA device structure.
 625 * @ata_dev:    ata_dev structure.
 626 *
 627 * Initialize an ATA device structure for sysfs.  It will be added in the
 628 * device tree below the ATA LINK device it belongs to.
 629 *
 630 * Returns %0 on success
 631 */
 632static int ata_tdev_add(struct ata_device *ata_dev)
 633{
 634        struct device *dev = &ata_dev->tdev;
 635        struct ata_link *link = ata_dev->link;
 636        struct ata_port *ap = link->ap;
 637        int error;
 638
 639        device_initialize(dev);
 640        dev->parent = get_device(&link->tdev);
 641        dev->release = ata_tdev_release;
 642        if (ata_is_host_link(link))
 643                dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno);
 644        else
 645                dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
 646
 647        transport_setup_device(dev);
 648        ata_acpi_bind_dev(ata_dev);
 649        error = device_add(dev);
 650        if (error) {
 651                ata_tdev_free(ata_dev);
 652                return error;
 653        }
 654
 655        transport_add_device(dev);
 656        transport_configure_device(dev);
 657        return 0;
 658}
 659
 660
 661/*
 662 * Setup / Teardown code
 663 */
 664
 665#define SETUP_TEMPLATE(attrb, field, perm, test)                        \
 666        i->private_##attrb[count] = dev_attr_##field;                   \
 667        i->private_##attrb[count].attr.mode = perm;                     \
 668        i->attrb[count] = &i->private_##attrb[count];                   \
 669        if (test)                                                       \
 670                count++
 671
 672#define SETUP_LINK_ATTRIBUTE(field)                                     \
 673        SETUP_TEMPLATE(link_attrs, field, S_IRUGO, 1)
 674
 675#define SETUP_PORT_ATTRIBUTE(field)                                     \
 676        SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
 677
 678#define SETUP_DEV_ATTRIBUTE(field)                                      \
 679        SETUP_TEMPLATE(dev_attrs, field, S_IRUGO, 1)
 680
 681/**
 682 * ata_attach_transport  --  instantiate ATA transport template
 683 */
 684struct scsi_transport_template *ata_attach_transport(void)
 685{
 686        struct ata_internal *i;
 687        int count;
 688
 689        i = kzalloc(sizeof(struct ata_internal), GFP_KERNEL);
 690        if (!i)
 691                return NULL;
 692
 693        i->t.eh_strategy_handler        = ata_scsi_error;
 694        i->t.eh_timed_out               = ata_scsi_timed_out;
 695        i->t.user_scan                  = ata_scsi_user_scan;
 696
 697        i->t.host_attrs.ac.attrs = &i->port_attrs[0];
 698        i->t.host_attrs.ac.class = &ata_port_class.class;
 699        i->t.host_attrs.ac.match = ata_tport_match;
 700        transport_container_register(&i->t.host_attrs);
 701
 702        i->link_attr_cont.ac.class = &ata_link_class.class;
 703        i->link_attr_cont.ac.attrs = &i->link_attrs[0];
 704        i->link_attr_cont.ac.match = ata_tlink_match;
 705        transport_container_register(&i->link_attr_cont);
 706
 707        i->dev_attr_cont.ac.class = &ata_dev_class.class;
 708        i->dev_attr_cont.ac.attrs = &i->dev_attrs[0];
 709        i->dev_attr_cont.ac.match = ata_tdev_match;
 710        transport_container_register(&i->dev_attr_cont);
 711
 712        count = 0;
 713        SETUP_PORT_ATTRIBUTE(nr_pmp_links);
 714        SETUP_PORT_ATTRIBUTE(idle_irq);
 715        SETUP_PORT_ATTRIBUTE(port_no);
 716        BUG_ON(count > ATA_PORT_ATTRS);
 717        i->port_attrs[count] = NULL;
 718
 719        count = 0;
 720        SETUP_LINK_ATTRIBUTE(hw_sata_spd_limit);
 721        SETUP_LINK_ATTRIBUTE(sata_spd_limit);
 722        SETUP_LINK_ATTRIBUTE(sata_spd);
 723        BUG_ON(count > ATA_LINK_ATTRS);
 724        i->link_attrs[count] = NULL;
 725
 726        count = 0;
 727        SETUP_DEV_ATTRIBUTE(class);
 728        SETUP_DEV_ATTRIBUTE(pio_mode);
 729        SETUP_DEV_ATTRIBUTE(dma_mode);
 730        SETUP_DEV_ATTRIBUTE(xfer_mode);
 731        SETUP_DEV_ATTRIBUTE(spdn_cnt);
 732        SETUP_DEV_ATTRIBUTE(ering);
 733        SETUP_DEV_ATTRIBUTE(id);
 734        SETUP_DEV_ATTRIBUTE(gscr);
 735        BUG_ON(count > ATA_DEV_ATTRS);
 736        i->dev_attrs[count] = NULL;
 737
 738        return &i->t;
 739}
 740
 741/**
 742 * ata_release_transport  --  release ATA transport template instance
 743 * @t:          transport template instance
 744 */
 745void ata_release_transport(struct scsi_transport_template *t)
 746{
 747        struct ata_internal *i = to_ata_internal(t);
 748
 749        transport_container_unregister(&i->t.host_attrs);
 750        transport_container_unregister(&i->link_attr_cont);
 751        transport_container_unregister(&i->dev_attr_cont);
 752
 753        kfree(i);
 754}
 755
 756__init int libata_transport_init(void)
 757{
 758        int error;
 759
 760        error = transport_class_register(&ata_link_class);
 761        if (error)
 762                goto out_unregister_transport;
 763        error = transport_class_register(&ata_port_class);
 764        if (error)
 765                goto out_unregister_link;
 766        error = transport_class_register(&ata_dev_class);
 767        if (error)
 768                goto out_unregister_port;
 769        return 0;
 770
 771 out_unregister_port:
 772        transport_class_unregister(&ata_port_class);
 773 out_unregister_link:
 774        transport_class_unregister(&ata_link_class);
 775 out_unregister_transport:
 776        return error;
 777
 778}
 779
 780void __exit libata_transport_exit(void)
 781{
 782        transport_class_unregister(&ata_link_class);
 783        transport_class_unregister(&ata_port_class);
 784        transport_class_unregister(&ata_dev_class);
 785}
 786
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.