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          2
  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);
 219
 220static DECLARE_TRANSPORT_CLASS(ata_port_class,
 221                               "ata_port", NULL, NULL, NULL);
 222
 223static void ata_tport_release(struct device *dev)
 224{
 225        put_device(dev->parent);
 226}
 227
 228/**
 229 * ata_is_port --  check if a struct device represents a ATA port
 230 * @dev:        device to check
 231 *
 232 * Returns:
 233 *      %1 if the device represents a ATA Port, %0 else
 234 */
 235static int ata_is_port(const struct device *dev)
 236{
 237        return dev->release == ata_tport_release;
 238}
 239
 240static int ata_tport_match(struct attribute_container *cont,
 241                           struct device *dev)
 242{
 243        if (!ata_is_port(dev))
 244                return 0;
 245        return &ata_scsi_transport_template->host_attrs.ac == cont;
 246}
 247
 248/**
 249 * ata_tport_delete  --  remove ATA PORT
 250 * @port:       ATA PORT to remove
 251 *
 252 * Removes the specified ATA PORT.  Remove the associated link as well.
 253 */
 254void ata_tport_delete(struct ata_port *ap)
 255{
 256        struct device *dev = &ap->tdev;
 257
 258        ata_tlink_delete(&ap->link);
 259
 260        transport_remove_device(dev);
 261        device_del(dev);
 262        transport_destroy_device(dev);
 263        put_device(dev);
 264}
 265
 266/** ata_tport_add - initialize a transport ATA port structure
 267 *
 268 * @parent:     parent device
 269 * @ap:         existing ata_port structure
 270 *
 271 * Initialize a ATA port structure for sysfs.  It will be added to the device
 272 * tree below the device specified by @parent which could be a PCI device.
 273 *
 274 * Returns %0 on success
 275 */
 276int ata_tport_add(struct device *parent,
 277                  struct ata_port *ap)
 278{
 279        int error;
 280        struct device *dev = &ap->tdev;
 281
 282        device_initialize(dev);
 283        dev->type = &ata_port_type;
 284
 285        dev->parent = get_device(parent);
 286        dev->release = ata_tport_release;
 287        dev_set_name(dev, "ata%d", ap->print_id);
 288        transport_setup_device(dev);
 289        error = device_add(dev);
 290        if (error) {
 291                goto tport_err;
 292        }
 293
 294        device_enable_async_suspend(dev);
 295        pm_runtime_set_active(dev);
 296        pm_runtime_enable(dev);
 297        pm_runtime_forbid(dev);
 298
 299        transport_add_device(dev);
 300        transport_configure_device(dev);
 301
 302        error = ata_tlink_add(&ap->link);
 303        if (error) {
 304                goto tport_link_err;
 305        }
 306        return 0;
 307
 308 tport_link_err:
 309        transport_remove_device(dev);
 310        device_del(dev);
 311
 312 tport_err:
 313        transport_destroy_device(dev);
 314        put_device(dev);
 315        return error;
 316}
 317
 318
 319/*
 320 * ATA link attributes
 321 */
 322
 323
 324#define ata_link_show_linkspeed(field)                                  \
 325static ssize_t                                                          \
 326show_ata_link_##field(struct device *dev,                               \
 327                      struct device_attribute *attr, char *buf)         \
 328{                                                                       \
 329        struct ata_link *link = transport_class_to_link(dev);           \
 330                                                                        \
 331        return sprintf(buf,"%s\n", sata_spd_string(fls(link->field)));  \
 332}
 333
 334#define ata_link_linkspeed_attr(field)                                  \
 335        ata_link_show_linkspeed(field)                                  \
 336static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL)
 337
 338ata_link_linkspeed_attr(hw_sata_spd_limit);
 339ata_link_linkspeed_attr(sata_spd_limit);
 340ata_link_linkspeed_attr(sata_spd);
 341
 342
 343static DECLARE_TRANSPORT_CLASS(ata_link_class,
 344                "ata_link", NULL, NULL, NULL);
 345
 346static void ata_tlink_release(struct device *dev)
 347{
 348        put_device(dev->parent);
 349}
 350
 351/**
 352 * ata_is_link --  check if a struct device represents a ATA link
 353 * @dev:        device to check
 354 *
 355 * Returns:
 356 *      %1 if the device represents a ATA link, %0 else
 357 */
 358static int ata_is_link(const struct device *dev)
 359{
 360        return dev->release == ata_tlink_release;
 361}
 362
 363static int ata_tlink_match(struct attribute_container *cont,
 364                           struct device *dev)
 365{
 366        struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
 367        if (!ata_is_link(dev))
 368                return 0;
 369        return &i->link_attr_cont.ac == cont;
 370}
 371
 372/**
 373 * ata_tlink_delete  --  remove ATA LINK
 374 * @port:       ATA LINK to remove
 375 *
 376 * Removes the specified ATA LINK.  remove associated ATA device(s) as well.
 377 */
 378void ata_tlink_delete(struct ata_link *link)
 379{
 380        struct device *dev = &link->tdev;
 381        struct ata_device *ata_dev;
 382
 383        ata_for_each_dev(ata_dev, link, ALL) {
 384                ata_tdev_delete(ata_dev);
 385        }
 386
 387        transport_remove_device(dev);
 388        device_del(dev);
 389        transport_destroy_device(dev);
 390        put_device(dev);
 391}
 392
 393/**
 394 * ata_tlink_add  --  initialize a transport ATA link structure
 395 * @link:       allocated ata_link structure.
 396 *
 397 * Initialize an ATA LINK structure for sysfs.  It will be added in the
 398 * device tree below the ATA PORT it belongs to.
 399 *
 400 * Returns %0 on success
 401 */
 402int ata_tlink_add(struct ata_link *link)
 403{
 404        struct device *dev = &link->tdev;
 405        struct ata_port *ap = link->ap;
 406        struct ata_device *ata_dev;
 407        int error;
 408
 409        device_initialize(dev);
 410        dev->parent = get_device(&ap->tdev);
 411        dev->release = ata_tlink_release;
 412        if (ata_is_host_link(link))
 413                dev_set_name(dev, "link%d", ap->print_id);
 414        else
 415                dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp);
 416
 417        transport_setup_device(dev);
 418
 419        error = device_add(dev);
 420        if (error) {
 421                goto tlink_err;
 422        }
 423
 424        transport_add_device(dev);
 425        transport_configure_device(dev);
 426
 427        ata_for_each_dev(ata_dev, link, ALL) {
 428                error = ata_tdev_add(ata_dev);
 429                if (error) {
 430                        goto tlink_dev_err;
 431                }
 432        }
 433        return 0;
 434  tlink_dev_err:
 435        while (--ata_dev >= link->device) {
 436                ata_tdev_delete(ata_dev);
 437        }
 438        transport_remove_device(dev);
 439        device_del(dev);
 440  tlink_err:
 441        transport_destroy_device(dev);
 442        put_device(dev);
 443        return error;
 444}
 445
 446/*
 447 * ATA device attributes
 448 */
 449
 450#define ata_dev_show_class(title, field)                                \
 451static ssize_t                                                          \
 452show_ata_dev_##field(struct device *dev,                                \
 453                     struct device_attribute *attr, char *buf)          \
 454{                                                                       \
 455        struct ata_device *ata_dev = transport_class_to_dev(dev);       \
 456                                                                        \
 457        return get_ata_##title##_names(ata_dev->field, buf);            \
 458}
 459
 460#define ata_dev_attr(title, field)                                      \
 461        ata_dev_show_class(title, field)                                \
 462static DEVICE_ATTR(field, S_IRUGO, show_ata_dev_##field, NULL)
 463
 464ata_dev_attr(class, class);
 465ata_dev_attr(xfer, pio_mode);
 466ata_dev_attr(xfer, dma_mode);
 467ata_dev_attr(xfer, xfer_mode);
 468
 469
 470#define ata_dev_show_simple(field, format_string, cast)         \
 471static ssize_t                                                          \
 472show_ata_dev_##field(struct device *dev,                                \
 473                     struct device_attribute *attr, char *buf)          \
 474{                                                                       \
 475        struct ata_device *ata_dev = transport_class_to_dev(dev);       \
 476                                                                        \
 477        return snprintf(buf, 20, format_string, cast ata_dev->field);   \
 478}
 479
 480#define ata_dev_simple_attr(field, format_string, type) \
 481        ata_dev_show_simple(field, format_string, (type))       \
 482static DEVICE_ATTR(field, S_IRUGO,                      \
 483                   show_ata_dev_##field, NULL)
 484
 485ata_dev_simple_attr(spdn_cnt, "%d\n", int);
 486
 487struct ata_show_ering_arg {
 488        char* buf;
 489        int written;
 490};
 491
 492static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
 493{
 494        struct ata_show_ering_arg* arg = void_arg;
 495        struct timespec time;
 496
 497        jiffies_to_timespec(ent->timestamp,&time);
 498        arg->written += sprintf(arg->buf + arg->written,
 499                               "[%5lu.%06lu]",
 500                               time.tv_sec, time.tv_nsec);
 501        arg->written += get_ata_err_names(ent->err_mask,
 502                                          arg->buf + arg->written);
 503        return 0;
 504}
 505
 506static ssize_t
 507show_ata_dev_ering(struct device *dev,
 508                   struct device_attribute *attr, char *buf)
 509{
 510        struct ata_device *ata_dev = transport_class_to_dev(dev);
 511        struct ata_show_ering_arg arg = { buf, 0 };
 512
 513        ata_ering_map(&ata_dev->ering, ata_show_ering, &arg);
 514        return arg.written;
 515}
 516
 517
 518static DEVICE_ATTR(ering, S_IRUGO, show_ata_dev_ering, NULL);
 519
 520static ssize_t
 521show_ata_dev_id(struct device *dev,
 522                struct device_attribute *attr, char *buf)
 523{
 524        struct ata_device *ata_dev = transport_class_to_dev(dev);
 525        int written = 0, i = 0;
 526
 527        if (ata_dev->class == ATA_DEV_PMP)
 528                return 0;
 529        for(i=0;i<ATA_ID_WORDS;i++)  {
 530                written += snprintf(buf+written, 20, "%04x%c",
 531                                    ata_dev->id[i],
 532                                    ((i+1) & 7) ? ' ' : '\n');
 533        }
 534        return written;
 535}
 536
 537static DEVICE_ATTR(id, S_IRUGO, show_ata_dev_id, NULL);
 538
 539static ssize_t
 540show_ata_dev_gscr(struct device *dev,
 541                  struct device_attribute *attr, char *buf)
 542{
 543        struct ata_device *ata_dev = transport_class_to_dev(dev);
 544        int written = 0, i = 0;
 545
 546        if (ata_dev->class != ATA_DEV_PMP)
 547                return 0;
 548        for(i=0;i<SATA_PMP_GSCR_DWORDS;i++)  {
 549                written += snprintf(buf+written, 20, "%08x%c",
 550                                    ata_dev->gscr[i],
 551                                    ((i+1) & 3) ? ' ' : '\n');
 552        }
 553        if (SATA_PMP_GSCR_DWORDS & 3)
 554                buf[written-1] = '\n';
 555        return written;
 556}
 557
 558static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL);
 559
 560static DECLARE_TRANSPORT_CLASS(ata_dev_class,
 561                               "ata_device", NULL, NULL, NULL);
 562
 563static void ata_tdev_release(struct device *dev)
 564{
 565        put_device(dev->parent);
 566}
 567
 568/**
 569 * ata_is_ata_dev  --  check if a struct device represents a ATA device
 570 * @dev:        device to check
 571 *
 572 * Returns:
 573 *      %1 if the device represents a ATA device, %0 else
 574 */
 575static int ata_is_ata_dev(const struct device *dev)
 576{
 577        return dev->release == ata_tdev_release;
 578}
 579
 580static int ata_tdev_match(struct attribute_container *cont,
 581                          struct device *dev)
 582{
 583        struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
 584        if (!ata_is_ata_dev(dev))
 585                return 0;
 586        return &i->dev_attr_cont.ac == cont;
 587}
 588
 589/**
 590 * ata_tdev_free  --  free a ATA LINK
 591 * @dev:        ATA PHY to free
 592 *
 593 * Frees the specified ATA PHY.
 594 *
 595 * Note:
 596 *   This function must only be called on a PHY that has not
 597 *   successfully been added using ata_tdev_add().
 598 */
 599static void ata_tdev_free(struct ata_device *dev)
 600{
 601        transport_destroy_device(&dev->tdev);
 602        put_device(&dev->tdev);
 603}
 604
 605/**
 606 * ata_tdev_delete  --  remove ATA device
 607 * @port:       ATA PORT to remove
 608 *
 609 * Removes the specified ATA device.
 610 */
 611static void ata_tdev_delete(struct ata_device *ata_dev)
 612{
 613        struct device *dev = &ata_dev->tdev;
 614
 615        transport_remove_device(dev);
 616        device_del(dev);
 617        ata_tdev_free(ata_dev);
 618}
 619
 620
 621/**
 622 * ata_tdev_add  --  initialize a transport ATA device structure.
 623 * @ata_dev:    ata_dev structure.
 624 *
 625 * Initialize an ATA device structure for sysfs.  It will be added in the
 626 * device tree below the ATA LINK device it belongs to.
 627 *
 628 * Returns %0 on success
 629 */
 630static int ata_tdev_add(struct ata_device *ata_dev)
 631{
 632        struct device *dev = &ata_dev->tdev;
 633        struct ata_link *link = ata_dev->link;
 634        struct ata_port *ap = link->ap;
 635        int error;
 636
 637        device_initialize(dev);
 638        dev->parent = get_device(&link->tdev);
 639        dev->release = ata_tdev_release;
 640        if (ata_is_host_link(link))
 641                dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno);
 642        else
 643                dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
 644
 645        transport_setup_device(dev);
 646        error = device_add(dev);
 647        if (error) {
 648                ata_tdev_free(ata_dev);
 649                return error;
 650        }
 651
 652        transport_add_device(dev);
 653        transport_configure_device(dev);
 654        return 0;
 655}
 656
 657
 658/*
 659 * Setup / Teardown code
 660 */
 661
 662#define SETUP_TEMPLATE(attrb, field, perm, test)                        \
 663        i->private_##attrb[count] = dev_attr_##field;                   \
 664        i->private_##attrb[count].attr.mode = perm;                     \
 665        i->attrb[count] = &i->private_##attrb[count];                   \
 666        if (test)                                                       \
 667                count++
 668
 669#define SETUP_LINK_ATTRIBUTE(field)                                     \
 670        SETUP_TEMPLATE(link_attrs, field, S_IRUGO, 1)
 671
 672#define SETUP_PORT_ATTRIBUTE(field)                                     \
 673        SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
 674
 675#define SETUP_DEV_ATTRIBUTE(field)                                      \
 676        SETUP_TEMPLATE(dev_attrs, field, S_IRUGO, 1)
 677
 678/**
 679 * ata_attach_transport  --  instantiate ATA transport template
 680 */
 681struct scsi_transport_template *ata_attach_transport(void)
 682{
 683        struct ata_internal *i;
 684        int count;
 685
 686        i = kzalloc(sizeof(struct ata_internal), GFP_KERNEL);
 687        if (!i)
 688                return NULL;
 689
 690        i->t.eh_strategy_handler        = ata_scsi_error;
 691        i->t.eh_timed_out               = ata_scsi_timed_out;
 692        i->t.user_scan                  = ata_scsi_user_scan;
 693
 694        i->t.host_attrs.ac.attrs = &i->port_attrs[0];
 695        i->t.host_attrs.ac.class = &ata_port_class.class;
 696        i->t.host_attrs.ac.match = ata_tport_match;
 697        transport_container_register(&i->t.host_attrs);
 698
 699        i->link_attr_cont.ac.class = &ata_link_class.class;
 700        i->link_attr_cont.ac.attrs = &i->link_attrs[0];
 701        i->link_attr_cont.ac.match = ata_tlink_match;
 702        transport_container_register(&i->link_attr_cont);
 703
 704        i->dev_attr_cont.ac.class = &ata_dev_class.class;
 705        i->dev_attr_cont.ac.attrs = &i->dev_attrs[0];
 706        i->dev_attr_cont.ac.match = ata_tdev_match;
 707        transport_container_register(&i->dev_attr_cont);
 708
 709        count = 0;
 710        SETUP_PORT_ATTRIBUTE(nr_pmp_links);
 711        SETUP_PORT_ATTRIBUTE(idle_irq);
 712        BUG_ON(count > ATA_PORT_ATTRS);
 713        i->port_attrs[count] = NULL;
 714
 715        count = 0;
 716        SETUP_LINK_ATTRIBUTE(hw_sata_spd_limit);
 717        SETUP_LINK_ATTRIBUTE(sata_spd_limit);
 718        SETUP_LINK_ATTRIBUTE(sata_spd);
 719        BUG_ON(count > ATA_LINK_ATTRS);
 720        i->link_attrs[count] = NULL;
 721
 722        count = 0;
 723        SETUP_DEV_ATTRIBUTE(class);
 724        SETUP_DEV_ATTRIBUTE(pio_mode);
 725        SETUP_DEV_ATTRIBUTE(dma_mode);
 726        SETUP_DEV_ATTRIBUTE(xfer_mode);
 727        SETUP_DEV_ATTRIBUTE(spdn_cnt);
 728        SETUP_DEV_ATTRIBUTE(ering);
 729        SETUP_DEV_ATTRIBUTE(id);
 730        SETUP_DEV_ATTRIBUTE(gscr);
 731        BUG_ON(count > ATA_DEV_ATTRS);
 732        i->dev_attrs[count] = NULL;
 733
 734        return &i->t;
 735}
 736
 737/**
 738 * ata_release_transport  --  release ATA transport template instance
 739 * @t:          transport template instance
 740 */
 741void ata_release_transport(struct scsi_transport_template *t)
 742{
 743        struct ata_internal *i = to_ata_internal(t);
 744
 745        transport_container_unregister(&i->t.host_attrs);
 746        transport_container_unregister(&i->link_attr_cont);
 747        transport_container_unregister(&i->dev_attr_cont);
 748
 749        kfree(i);
 750}
 751
 752__init int libata_transport_init(void)
 753{
 754        int error;
 755
 756        error = transport_class_register(&ata_link_class);
 757        if (error)
 758                goto out_unregister_transport;
 759        error = transport_class_register(&ata_port_class);
 760        if (error)
 761                goto out_unregister_link;
 762        error = transport_class_register(&ata_dev_class);
 763        if (error)
 764                goto out_unregister_port;
 765        return 0;
 766
 767 out_unregister_port:
 768        transport_class_unregister(&ata_port_class);
 769 out_unregister_link:
 770        transport_class_unregister(&ata_link_class);
 771 out_unregister_transport:
 772        return error;
 773
 774}
 775
 776void __exit libata_transport_exit(void)
 777{
 778        transport_class_unregister(&ata_link_class);
 779        transport_class_unregister(&ata_port_class);
 780        transport_class_unregister(&ata_dev_class);
 781}
 782
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.