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