Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * Copyright 2008 ioogle, Inc. All rights reserved.
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 : :
44 : : struct scsi_transport_template;
45 : : struct scsi_transport_template *ata_scsi_transport_template;
46 : :
47 : : struct 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 */
85 : : static int ata_tdev_add(struct ata_device *dev);
86 : : static 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) \
97 : : static ssize_t \
98 : : get_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) \
116 : : static ssize_t \
117 : : get_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 : :
133 : : static 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_ZAC, "zac" },
147 : : { ATA_DEV_NONE, "none" }
148 : : };
149 [ # # # # ]: 0 : ata_bitfield_name_search(class, ata_class_names)
150 : :
151 : :
152 : : static struct {
153 : : u32 value;
154 : : char *name;
155 : : } ata_err_names[] = {
156 : : { AC_ERR_DEV, "DeviceError" },
157 : : { AC_ERR_HSM, "HostStateMachineError" },
158 : : { AC_ERR_TIMEOUT, "Timeout" },
159 : : { AC_ERR_MEDIA, "MediaError" },
160 : : { AC_ERR_ATA_BUS, "BusError" },
161 : : { AC_ERR_HOST_BUS, "HostBusError" },
162 : : { AC_ERR_SYSTEM, "SystemError" },
163 : : { AC_ERR_INVALID, "InvalidArg" },
164 : : { AC_ERR_OTHER, "Unknown" },
165 : : { AC_ERR_NODEV_HINT, "NoDeviceHint" },
166 : : { AC_ERR_NCQ, "NCQError" }
167 : : };
168 [ # # # # ]: 0 : ata_bitfield_name_match(err, ata_err_names)
169 : :
170 : : static struct {
171 : : u32 value;
172 : : char *name;
173 : : } ata_xfer_names[] = {
174 : : { XFER_UDMA_7, "XFER_UDMA_7" },
175 : : { XFER_UDMA_6, "XFER_UDMA_6" },
176 : : { XFER_UDMA_5, "XFER_UDMA_5" },
177 : : { XFER_UDMA_4, "XFER_UDMA_4" },
178 : : { XFER_UDMA_3, "XFER_UDMA_3" },
179 : : { XFER_UDMA_2, "XFER_UDMA_2" },
180 : : { XFER_UDMA_1, "XFER_UDMA_1" },
181 : : { XFER_UDMA_0, "XFER_UDMA_0" },
182 : : { XFER_MW_DMA_4, "XFER_MW_DMA_4" },
183 : : { XFER_MW_DMA_3, "XFER_MW_DMA_3" },
184 : : { XFER_MW_DMA_2, "XFER_MW_DMA_2" },
185 : : { XFER_MW_DMA_1, "XFER_MW_DMA_1" },
186 : : { XFER_MW_DMA_0, "XFER_MW_DMA_0" },
187 : : { XFER_SW_DMA_2, "XFER_SW_DMA_2" },
188 : : { XFER_SW_DMA_1, "XFER_SW_DMA_1" },
189 : : { XFER_SW_DMA_0, "XFER_SW_DMA_0" },
190 : : { XFER_PIO_6, "XFER_PIO_6" },
191 : : { XFER_PIO_5, "XFER_PIO_5" },
192 : : { XFER_PIO_4, "XFER_PIO_4" },
193 : : { XFER_PIO_3, "XFER_PIO_3" },
194 : : { XFER_PIO_2, "XFER_PIO_2" },
195 : : { XFER_PIO_1, "XFER_PIO_1" },
196 : : { XFER_PIO_0, "XFER_PIO_0" },
197 : : { XFER_PIO_SLOW, "XFER_PIO_SLOW" }
198 : : };
199 [ # # # # ]: 0 : ata_bitfield_name_match(xfer,ata_xfer_names)
200 : :
201 : : /*
202 : : * ATA Port attributes
203 : : */
204 : : #define ata_port_show_simple(field, name, format_string, cast) \
205 : : static ssize_t \
206 : : show_ata_port_##name(struct device *dev, \
207 : : struct device_attribute *attr, char *buf) \
208 : : { \
209 : : struct ata_port *ap = transport_class_to_port(dev); \
210 : : \
211 : : return snprintf(buf, 20, format_string, cast ap->field); \
212 : : }
213 : :
214 : : #define ata_port_simple_attr(field, name, format_string, type) \
215 : : ata_port_show_simple(field, name, format_string, (type)) \
216 : : static DEVICE_ATTR(name, S_IRUGO, show_ata_port_##name, NULL)
217 : :
218 : 0 : ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int);
219 : 0 : ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long);
220 : 84 : ata_port_simple_attr(local_port_no, port_no, "%u\n", unsigned int);
221 : :
222 : : static DECLARE_TRANSPORT_CLASS(ata_port_class,
223 : : "ata_port", NULL, NULL, NULL);
224 : :
225 : 0 : static void ata_tport_release(struct device *dev)
226 : : {
227 : 0 : struct ata_port *ap = tdev_to_port(dev);
228 : 0 : ata_host_put(ap->host);
229 : 0 : }
230 : :
231 : : /**
232 : : * ata_is_port -- check if a struct device represents a ATA port
233 : : * @dev: device to check
234 : : *
235 : : * Returns:
236 : : * %1 if the device represents a ATA Port, %0 else
237 : : */
238 : 1008 : static int ata_is_port(const struct device *dev)
239 : : {
240 : 1008 : return dev->release == ata_tport_release;
241 : : }
242 : :
243 : 1008 : static int ata_tport_match(struct attribute_container *cont,
244 : : struct device *dev)
245 : : {
246 [ + + ]: 1008 : if (!ata_is_port(dev))
247 : : return 0;
248 : 126 : return &ata_scsi_transport_template->host_attrs.ac == cont;
249 : : }
250 : :
251 : : /**
252 : : * ata_tport_delete -- remove ATA PORT
253 : : * @port: ATA PORT to remove
254 : : *
255 : : * Removes the specified ATA PORT. Remove the associated link as well.
256 : : */
257 : 0 : void ata_tport_delete(struct ata_port *ap)
258 : : {
259 : 0 : struct device *dev = &ap->tdev;
260 : :
261 : 0 : ata_tlink_delete(&ap->link);
262 : :
263 : 0 : transport_remove_device(dev);
264 : 0 : device_del(dev);
265 : 0 : transport_destroy_device(dev);
266 : 0 : put_device(dev);
267 : 0 : }
268 : :
269 : : /** ata_tport_add - initialize a transport ATA port structure
270 : : *
271 : : * @parent: parent device
272 : : * @ap: existing ata_port structure
273 : : *
274 : : * Initialize a ATA port structure for sysfs. It will be added to the device
275 : : * tree below the device specified by @parent which could be a PCI device.
276 : : *
277 : : * Returns %0 on success
278 : : */
279 : 42 : int ata_tport_add(struct device *parent,
280 : : struct ata_port *ap)
281 : : {
282 : 42 : int error;
283 : 42 : struct device *dev = &ap->tdev;
284 : :
285 : 42 : device_initialize(dev);
286 : 42 : dev->type = &ata_port_type;
287 : :
288 : 42 : dev->parent = parent;
289 : 42 : ata_host_get(ap->host);
290 : 42 : dev->release = ata_tport_release;
291 : 42 : dev_set_name(dev, "ata%d", ap->print_id);
292 : 42 : transport_setup_device(dev);
293 : 42 : ata_acpi_bind_port(ap);
294 : 42 : error = device_add(dev);
295 [ - + ]: 42 : if (error) {
296 : 0 : goto tport_err;
297 : : }
298 : :
299 [ + - ]: 42 : device_enable_async_suspend(dev);
300 : 42 : pm_runtime_set_active(dev);
301 : 42 : pm_runtime_enable(dev);
302 : 42 : pm_runtime_forbid(dev);
303 : :
304 : 42 : transport_add_device(dev);
305 : 42 : transport_configure_device(dev);
306 : :
307 : 42 : error = ata_tlink_add(&ap->link);
308 [ - + ]: 42 : if (error) {
309 : 0 : goto tport_link_err;
310 : : }
311 : : return 0;
312 : :
313 : : tport_link_err:
314 : 0 : transport_remove_device(dev);
315 : 0 : device_del(dev);
316 : :
317 : 0 : tport_err:
318 : 0 : transport_destroy_device(dev);
319 : 0 : put_device(dev);
320 : 0 : ata_host_put(ap->host);
321 : 0 : return error;
322 : : }
323 : :
324 : :
325 : : /*
326 : : * ATA link attributes
327 : : */
328 : 0 : static int noop(int x) { return x; }
329 : :
330 : : #define ata_link_show_linkspeed(field, format) \
331 : : static ssize_t \
332 : : show_ata_link_##field(struct device *dev, \
333 : : struct device_attribute *attr, char *buf) \
334 : : { \
335 : : struct ata_link *link = transport_class_to_link(dev); \
336 : : \
337 : : return sprintf(buf, "%s\n", sata_spd_string(format(link->field))); \
338 : : }
339 : :
340 : : #define ata_link_linkspeed_attr(field, format) \
341 : : ata_link_show_linkspeed(field, format) \
342 : : static DEVICE_ATTR(field, S_IRUGO, show_ata_link_##field, NULL)
343 : :
344 : 0 : ata_link_linkspeed_attr(hw_sata_spd_limit, fls);
345 : 0 : ata_link_linkspeed_attr(sata_spd_limit, fls);
346 : 0 : ata_link_linkspeed_attr(sata_spd, noop);
347 : :
348 : :
349 : : static DECLARE_TRANSPORT_CLASS(ata_link_class,
350 : : "ata_link", NULL, NULL, NULL);
351 : :
352 : 0 : static void ata_tlink_release(struct device *dev)
353 : : {
354 : 0 : }
355 : :
356 : : /**
357 : : * ata_is_link -- check if a struct device represents a ATA link
358 : : * @dev: device to check
359 : : *
360 : : * Returns:
361 : : * %1 if the device represents a ATA link, %0 else
362 : : */
363 : 1008 : static int ata_is_link(const struct device *dev)
364 : : {
365 : 1008 : return dev->release == ata_tlink_release;
366 : : }
367 : :
368 : 1008 : static int ata_tlink_match(struct attribute_container *cont,
369 : : struct device *dev)
370 : : {
371 : 1008 : struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
372 [ + + ]: 1008 : if (!ata_is_link(dev))
373 : : return 0;
374 : 126 : return &i->link_attr_cont.ac == cont;
375 : : }
376 : :
377 : : /**
378 : : * ata_tlink_delete -- remove ATA LINK
379 : : * @port: ATA LINK to remove
380 : : *
381 : : * Removes the specified ATA LINK. remove associated ATA device(s) as well.
382 : : */
383 : 0 : void ata_tlink_delete(struct ata_link *link)
384 : : {
385 : 0 : struct device *dev = &link->tdev;
386 : 0 : struct ata_device *ata_dev;
387 : :
388 [ # # ]: 0 : ata_for_each_dev(ata_dev, link, ALL) {
389 : 0 : ata_tdev_delete(ata_dev);
390 : : }
391 : :
392 : 0 : transport_remove_device(dev);
393 : 0 : device_del(dev);
394 : 0 : transport_destroy_device(dev);
395 : 0 : put_device(dev);
396 : 0 : }
397 : :
398 : : /**
399 : : * ata_tlink_add -- initialize a transport ATA link structure
400 : : * @link: allocated ata_link structure.
401 : : *
402 : : * Initialize an ATA LINK structure for sysfs. It will be added in the
403 : : * device tree below the ATA PORT it belongs to.
404 : : *
405 : : * Returns %0 on success
406 : : */
407 : 42 : int ata_tlink_add(struct ata_link *link)
408 : : {
409 : 42 : struct device *dev = &link->tdev;
410 : 42 : struct ata_port *ap = link->ap;
411 : 42 : struct ata_device *ata_dev;
412 : 42 : int error;
413 : :
414 : 42 : device_initialize(dev);
415 : 42 : dev->parent = &ap->tdev;
416 : 42 : dev->release = ata_tlink_release;
417 [ - + + - ]: 42 : if (ata_is_host_link(link))
418 : 42 : dev_set_name(dev, "link%d", ap->print_id);
419 : : else
420 : 0 : dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp);
421 : :
422 : 42 : transport_setup_device(dev);
423 : :
424 : 42 : error = device_add(dev);
425 [ - + ]: 42 : if (error) {
426 : 0 : goto tlink_err;
427 : : }
428 : :
429 : 42 : transport_add_device(dev);
430 : 42 : transport_configure_device(dev);
431 : :
432 [ + + ]: 126 : ata_for_each_dev(ata_dev, link, ALL) {
433 : 84 : error = ata_tdev_add(ata_dev);
434 [ - + ]: 84 : if (error) {
435 : 0 : goto tlink_dev_err;
436 : : }
437 : : }
438 : : return 0;
439 : : tlink_dev_err:
440 [ # # ]: 0 : while (--ata_dev >= link->device) {
441 : 0 : ata_tdev_delete(ata_dev);
442 : : }
443 : 0 : transport_remove_device(dev);
444 : 0 : device_del(dev);
445 : 0 : tlink_err:
446 : 0 : transport_destroy_device(dev);
447 : 0 : put_device(dev);
448 : 0 : return error;
449 : : }
450 : :
451 : : /*
452 : : * ATA device attributes
453 : : */
454 : :
455 : : #define ata_dev_show_class(title, field) \
456 : : static ssize_t \
457 : : show_ata_dev_##field(struct device *dev, \
458 : : struct device_attribute *attr, char *buf) \
459 : : { \
460 : : struct ata_device *ata_dev = transport_class_to_dev(dev); \
461 : : \
462 : : return get_ata_##title##_names(ata_dev->field, buf); \
463 : : }
464 : :
465 : : #define ata_dev_attr(title, field) \
466 : : ata_dev_show_class(title, field) \
467 : : static DEVICE_ATTR(field, S_IRUGO, show_ata_dev_##field, NULL)
468 : :
469 : 0 : ata_dev_attr(class, class);
470 : 0 : ata_dev_attr(xfer, pio_mode);
471 : 0 : ata_dev_attr(xfer, dma_mode);
472 : 0 : ata_dev_attr(xfer, xfer_mode);
473 : :
474 : :
475 : : #define ata_dev_show_simple(field, format_string, cast) \
476 : : static ssize_t \
477 : : show_ata_dev_##field(struct device *dev, \
478 : : struct device_attribute *attr, char *buf) \
479 : : { \
480 : : struct ata_device *ata_dev = transport_class_to_dev(dev); \
481 : : \
482 : : return snprintf(buf, 20, format_string, cast ata_dev->field); \
483 : : }
484 : :
485 : : #define ata_dev_simple_attr(field, format_string, type) \
486 : : ata_dev_show_simple(field, format_string, (type)) \
487 : : static DEVICE_ATTR(field, S_IRUGO, \
488 : : show_ata_dev_##field, NULL)
489 : :
490 : 0 : ata_dev_simple_attr(spdn_cnt, "%d\n", int);
491 : :
492 : : struct ata_show_ering_arg {
493 : : char* buf;
494 : : int written;
495 : : };
496 : :
497 : 0 : static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
498 : : {
499 : 0 : struct ata_show_ering_arg* arg = void_arg;
500 : 0 : u64 seconds;
501 : 0 : u32 rem;
502 : :
503 : 0 : seconds = div_u64_rem(ent->timestamp, HZ, &rem);
504 : 0 : arg->written += sprintf(arg->buf + arg->written,
505 : : "[%5llu.%09lu]", seconds,
506 : 0 : rem * NSEC_PER_SEC / HZ);
507 : 0 : arg->written += get_ata_err_names(ent->err_mask,
508 : 0 : arg->buf + arg->written);
509 : 0 : return 0;
510 : : }
511 : :
512 : : static ssize_t
513 : 0 : show_ata_dev_ering(struct device *dev,
514 : : struct device_attribute *attr, char *buf)
515 : : {
516 : 0 : struct ata_device *ata_dev = transport_class_to_dev(dev);
517 : 0 : struct ata_show_ering_arg arg = { buf, 0 };
518 : :
519 : 0 : ata_ering_map(&ata_dev->ering, ata_show_ering, &arg);
520 : 0 : return arg.written;
521 : : }
522 : :
523 : :
524 : : static DEVICE_ATTR(ering, S_IRUGO, show_ata_dev_ering, NULL);
525 : :
526 : : static ssize_t
527 : 0 : show_ata_dev_id(struct device *dev,
528 : : struct device_attribute *attr, char *buf)
529 : : {
530 : 0 : struct ata_device *ata_dev = transport_class_to_dev(dev);
531 : 0 : int written = 0, i = 0;
532 : :
533 [ # # ]: 0 : if (ata_dev->class == ATA_DEV_PMP)
534 : : return 0;
535 [ # # ]: 0 : for(i=0;i<ATA_ID_WORDS;i++) {
536 : 0 : written += snprintf(buf+written, 20, "%04x%c",
537 : 0 : ata_dev->id[i],
538 [ # # ]: 0 : ((i+1) & 7) ? ' ' : '\n');
539 : : }
540 : 0 : return written;
541 : : }
542 : :
543 : : static DEVICE_ATTR(id, S_IRUGO, show_ata_dev_id, NULL);
544 : :
545 : : static ssize_t
546 : 0 : show_ata_dev_gscr(struct device *dev,
547 : : struct device_attribute *attr, char *buf)
548 : : {
549 : 0 : struct ata_device *ata_dev = transport_class_to_dev(dev);
550 : 0 : int written = 0, i = 0;
551 : :
552 [ # # ]: 0 : if (ata_dev->class != ATA_DEV_PMP)
553 : : return 0;
554 [ # # ]: 0 : for(i=0;i<SATA_PMP_GSCR_DWORDS;i++) {
555 : 0 : written += snprintf(buf+written, 20, "%08x%c",
556 : : ata_dev->gscr[i],
557 [ # # ]: 0 : ((i+1) & 3) ? ' ' : '\n');
558 : : }
559 : 0 : if (SATA_PMP_GSCR_DWORDS & 3)
560 : : buf[written-1] = '\n';
561 : 0 : return written;
562 : : }
563 : :
564 : : static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL);
565 : :
566 : : static ssize_t
567 : 0 : show_ata_dev_trim(struct device *dev,
568 : : struct device_attribute *attr, char *buf)
569 : : {
570 : 0 : struct ata_device *ata_dev = transport_class_to_dev(dev);
571 : 0 : unsigned char *mode;
572 : :
573 [ # # # # ]: 0 : if (!ata_id_has_trim(ata_dev->id))
574 : : mode = "unsupported";
575 [ # # ]: 0 : else if (ata_dev->horkage & ATA_HORKAGE_NOTRIM)
576 : : mode = "forced_unsupported";
577 [ # # ]: 0 : else if (ata_dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM)
578 : : mode = "forced_unqueued";
579 [ # # # # ]: 0 : else if (ata_fpdma_dsm_supported(ata_dev))
580 : : mode = "queued";
581 : : else
582 : 0 : mode = "unqueued";
583 : :
584 : 0 : return snprintf(buf, 20, "%s\n", mode);
585 : : }
586 : :
587 : : static DEVICE_ATTR(trim, S_IRUGO, show_ata_dev_trim, NULL);
588 : :
589 : : static DECLARE_TRANSPORT_CLASS(ata_dev_class,
590 : : "ata_device", NULL, NULL, NULL);
591 : :
592 : 0 : static void ata_tdev_release(struct device *dev)
593 : : {
594 : 0 : }
595 : :
596 : : /**
597 : : * ata_is_ata_dev -- check if a struct device represents a ATA device
598 : : * @dev: device to check
599 : : *
600 : : * Returns:
601 : : * %1 if the device represents a ATA device, %0 else
602 : : */
603 : 1008 : static int ata_is_ata_dev(const struct device *dev)
604 : : {
605 : 1008 : return dev->release == ata_tdev_release;
606 : : }
607 : :
608 : 1008 : static int ata_tdev_match(struct attribute_container *cont,
609 : : struct device *dev)
610 : : {
611 : 1008 : struct ata_internal* i = to_ata_internal(ata_scsi_transport_template);
612 [ + + ]: 1008 : if (!ata_is_ata_dev(dev))
613 : : return 0;
614 : 252 : return &i->dev_attr_cont.ac == cont;
615 : : }
616 : :
617 : : /**
618 : : * ata_tdev_free -- free a ATA LINK
619 : : * @dev: ATA PHY to free
620 : : *
621 : : * Frees the specified ATA PHY.
622 : : *
623 : : * Note:
624 : : * This function must only be called on a PHY that has not
625 : : * successfully been added using ata_tdev_add().
626 : : */
627 : 0 : static void ata_tdev_free(struct ata_device *dev)
628 : : {
629 : 0 : transport_destroy_device(&dev->tdev);
630 : 0 : put_device(&dev->tdev);
631 : : }
632 : :
633 : : /**
634 : : * ata_tdev_delete -- remove ATA device
635 : : * @port: ATA PORT to remove
636 : : *
637 : : * Removes the specified ATA device.
638 : : */
639 : 0 : static void ata_tdev_delete(struct ata_device *ata_dev)
640 : : {
641 : 0 : struct device *dev = &ata_dev->tdev;
642 : :
643 : 0 : transport_remove_device(dev);
644 : 0 : device_del(dev);
645 : 0 : ata_tdev_free(ata_dev);
646 : 0 : }
647 : :
648 : :
649 : : /**
650 : : * ata_tdev_add -- initialize a transport ATA device structure.
651 : : * @ata_dev: ata_dev structure.
652 : : *
653 : : * Initialize an ATA device structure for sysfs. It will be added in the
654 : : * device tree below the ATA LINK device it belongs to.
655 : : *
656 : : * Returns %0 on success
657 : : */
658 : 84 : static int ata_tdev_add(struct ata_device *ata_dev)
659 : : {
660 : 84 : struct device *dev = &ata_dev->tdev;
661 : 84 : struct ata_link *link = ata_dev->link;
662 : 84 : struct ata_port *ap = link->ap;
663 : 84 : int error;
664 : :
665 : 84 : device_initialize(dev);
666 : 84 : dev->parent = &link->tdev;
667 : 84 : dev->release = ata_tdev_release;
668 [ - + + - ]: 84 : if (ata_is_host_link(link))
669 : 84 : dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno);
670 : : else
671 : 0 : dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp);
672 : :
673 : 84 : transport_setup_device(dev);
674 : 84 : ata_acpi_bind_dev(ata_dev);
675 : 84 : error = device_add(dev);
676 [ - + ]: 84 : if (error) {
677 : 0 : ata_tdev_free(ata_dev);
678 : 0 : return error;
679 : : }
680 : :
681 : 84 : transport_add_device(dev);
682 : 84 : transport_configure_device(dev);
683 : 84 : return 0;
684 : : }
685 : :
686 : :
687 : : /*
688 : : * Setup / Teardown code
689 : : */
690 : :
691 : : #define SETUP_TEMPLATE(attrb, field, perm, test) \
692 : : i->private_##attrb[count] = dev_attr_##field; \
693 : : i->private_##attrb[count].attr.mode = perm; \
694 : : i->attrb[count] = &i->private_##attrb[count]; \
695 : : if (test) \
696 : : count++
697 : :
698 : : #define SETUP_LINK_ATTRIBUTE(field) \
699 : : SETUP_TEMPLATE(link_attrs, field, S_IRUGO, 1)
700 : :
701 : : #define SETUP_PORT_ATTRIBUTE(field) \
702 : : SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
703 : :
704 : : #define SETUP_DEV_ATTRIBUTE(field) \
705 : : SETUP_TEMPLATE(dev_attrs, field, S_IRUGO, 1)
706 : :
707 : : /**
708 : : * ata_attach_transport -- instantiate ATA transport template
709 : : */
710 : 21 : struct scsi_transport_template *ata_attach_transport(void)
711 : : {
712 : 21 : struct ata_internal *i;
713 : 21 : int count;
714 : :
715 : 21 : i = kzalloc(sizeof(struct ata_internal), GFP_KERNEL);
716 [ + - ]: 21 : if (!i)
717 : : return NULL;
718 : :
719 : 21 : i->t.eh_strategy_handler = ata_scsi_error;
720 : 21 : i->t.user_scan = ata_scsi_user_scan;
721 : :
722 : 21 : i->t.host_attrs.ac.attrs = &i->port_attrs[0];
723 : 21 : i->t.host_attrs.ac.class = &ata_port_class.class;
724 : 21 : i->t.host_attrs.ac.match = ata_tport_match;
725 : 21 : transport_container_register(&i->t.host_attrs);
726 : :
727 : 21 : i->link_attr_cont.ac.class = &ata_link_class.class;
728 : 21 : i->link_attr_cont.ac.attrs = &i->link_attrs[0];
729 : 21 : i->link_attr_cont.ac.match = ata_tlink_match;
730 : 21 : transport_container_register(&i->link_attr_cont);
731 : :
732 : 21 : i->dev_attr_cont.ac.class = &ata_dev_class.class;
733 : 21 : i->dev_attr_cont.ac.attrs = &i->dev_attrs[0];
734 : 21 : i->dev_attr_cont.ac.match = ata_tdev_match;
735 : 21 : transport_container_register(&i->dev_attr_cont);
736 : :
737 : 21 : count = 0;
738 : 21 : SETUP_PORT_ATTRIBUTE(nr_pmp_links);
739 : 21 : SETUP_PORT_ATTRIBUTE(idle_irq);
740 : 21 : SETUP_PORT_ATTRIBUTE(port_no);
741 : 21 : BUG_ON(count > ATA_PORT_ATTRS);
742 : 21 : i->port_attrs[count] = NULL;
743 : :
744 : 21 : count = 0;
745 : 21 : SETUP_LINK_ATTRIBUTE(hw_sata_spd_limit);
746 : 21 : SETUP_LINK_ATTRIBUTE(sata_spd_limit);
747 : 21 : SETUP_LINK_ATTRIBUTE(sata_spd);
748 : 21 : BUG_ON(count > ATA_LINK_ATTRS);
749 : 21 : i->link_attrs[count] = NULL;
750 : :
751 : 21 : count = 0;
752 : 21 : SETUP_DEV_ATTRIBUTE(class);
753 : 21 : SETUP_DEV_ATTRIBUTE(pio_mode);
754 : 21 : SETUP_DEV_ATTRIBUTE(dma_mode);
755 : 21 : SETUP_DEV_ATTRIBUTE(xfer_mode);
756 : 21 : SETUP_DEV_ATTRIBUTE(spdn_cnt);
757 : 21 : SETUP_DEV_ATTRIBUTE(ering);
758 : 21 : SETUP_DEV_ATTRIBUTE(id);
759 : 21 : SETUP_DEV_ATTRIBUTE(gscr);
760 : 21 : SETUP_DEV_ATTRIBUTE(trim);
761 : 21 : BUG_ON(count > ATA_DEV_ATTRS);
762 : 21 : i->dev_attrs[count] = NULL;
763 : :
764 : 21 : return &i->t;
765 : : }
766 : :
767 : : /**
768 : : * ata_release_transport -- release ATA transport template instance
769 : : * @t: transport template instance
770 : : */
771 : 0 : void ata_release_transport(struct scsi_transport_template *t)
772 : : {
773 : 0 : struct ata_internal *i = to_ata_internal(t);
774 : :
775 : 0 : transport_container_unregister(&i->t.host_attrs);
776 : 0 : transport_container_unregister(&i->link_attr_cont);
777 : 0 : transport_container_unregister(&i->dev_attr_cont);
778 : :
779 : 0 : kfree(i);
780 : 0 : }
781 : :
782 : 21 : __init int libata_transport_init(void)
783 : : {
784 : 21 : int error;
785 : :
786 : 21 : error = transport_class_register(&ata_link_class);
787 [ - + ]: 21 : if (error)
788 : 0 : goto out_unregister_transport;
789 : 21 : error = transport_class_register(&ata_port_class);
790 [ - + ]: 21 : if (error)
791 : 0 : goto out_unregister_link;
792 : 21 : error = transport_class_register(&ata_dev_class);
793 [ - + ]: 21 : if (error)
794 : 0 : goto out_unregister_port;
795 : : return 0;
796 : :
797 : : out_unregister_port:
798 : 0 : transport_class_unregister(&ata_port_class);
799 : 0 : out_unregister_link:
800 : 0 : transport_class_unregister(&ata_link_class);
801 : : out_unregister_transport:
802 : : return error;
803 : :
804 : : }
805 : :
806 : 0 : void __exit libata_transport_exit(void)
807 : : {
808 : 0 : transport_class_unregister(&ata_link_class);
809 : 0 : transport_class_unregister(&ata_port_class);
810 : 0 : transport_class_unregister(&ata_dev_class);
811 : 0 : }
|