]> Git Repo - linux.git/blob - drivers/scsi/scsi_transport_sas.c
Merge tag 'docs-4.11' of git://git.lwn.net/linux
[linux.git] / drivers / scsi / scsi_transport_sas.c
1 /*
2  * Copyright (C) 2005-2006 Dell Inc.
3  *      Released under GPL v2.
4  *
5  * Serial Attached SCSI (SAS) transport class.
6  *
7  * The SAS transport class contains common code to deal with SAS HBAs,
8  * an aproximated representation of SAS topologies in the driver model,
9  * and various sysfs attributes to expose these topologies and management
10  * interfaces to userspace.
11  *
12  * In addition to the basic SCSI core objects this transport class
13  * introduces two additional intermediate objects:  The SAS PHY
14  * as represented by struct sas_phy defines an "outgoing" PHY on
15  * a SAS HBA or Expander, and the SAS remote PHY represented by
16  * struct sas_rphy defines an "incoming" PHY on a SAS Expander or
17  * end device.  Note that this is purely a software concept, the
18  * underlying hardware for a PHY and a remote PHY is the exactly
19  * the same.
20  *
21  * There is no concept of a SAS port in this code, users can see
22  * what PHYs form a wide port based on the port_identifier attribute,
23  * which is the same for all PHYs in a port.
24  */
25
26 #include <linux/init.h>
27 #include <linux/module.h>
28 #include <linux/jiffies.h>
29 #include <linux/err.h>
30 #include <linux/slab.h>
31 #include <linux/string.h>
32 #include <linux/blkdev.h>
33 #include <linux/bsg.h>
34
35 #include <scsi/scsi.h>
36 #include <scsi/scsi_request.h>
37 #include <scsi/scsi_device.h>
38 #include <scsi/scsi_host.h>
39 #include <scsi/scsi_transport.h>
40 #include <scsi/scsi_transport_sas.h>
41
42 #include "scsi_sas_internal.h"
43 struct sas_host_attrs {
44         struct list_head rphy_list;
45         struct mutex lock;
46         struct request_queue *q;
47         u32 next_target_id;
48         u32 next_expander_id;
49         int next_port_id;
50 };
51 #define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data)
52
53
54 /*
55  * Hack to allow attributes of the same name in different objects.
56  */
57 #define SAS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
58         struct device_attribute dev_attr_##_prefix##_##_name = \
59         __ATTR(_name,_mode,_show,_store)
60
61
62 /*
63  * Pretty printing helpers
64  */
65
66 #define sas_bitfield_name_match(title, table)                   \
67 static ssize_t                                                  \
68 get_sas_##title##_names(u32 table_key, char *buf)               \
69 {                                                               \
70         char *prefix = "";                                      \
71         ssize_t len = 0;                                        \
72         int i;                                                  \
73                                                                 \
74         for (i = 0; i < ARRAY_SIZE(table); i++) {               \
75                 if (table[i].value & table_key) {               \
76                         len += sprintf(buf + len, "%s%s",       \
77                                 prefix, table[i].name);         \
78                         prefix = ", ";                          \
79                 }                                               \
80         }                                                       \
81         len += sprintf(buf + len, "\n");                        \
82         return len;                                             \
83 }
84
85 #define sas_bitfield_name_set(title, table)                     \
86 static ssize_t                                                  \
87 set_sas_##title##_names(u32 *table_key, const char *buf)        \
88 {                                                               \
89         ssize_t len = 0;                                        \
90         int i;                                                  \
91                                                                 \
92         for (i = 0; i < ARRAY_SIZE(table); i++) {               \
93                 len = strlen(table[i].name);                    \
94                 if (strncmp(buf, table[i].name, len) == 0 &&    \
95                     (buf[len] == '\n' || buf[len] == '\0')) {   \
96                         *table_key = table[i].value;            \
97                         return 0;                               \
98                 }                                               \
99         }                                                       \
100         return -EINVAL;                                         \
101 }
102
103 #define sas_bitfield_name_search(title, table)                  \
104 static ssize_t                                                  \
105 get_sas_##title##_names(u32 table_key, char *buf)               \
106 {                                                               \
107         ssize_t len = 0;                                        \
108         int i;                                                  \
109                                                                 \
110         for (i = 0; i < ARRAY_SIZE(table); i++) {               \
111                 if (table[i].value == table_key) {              \
112                         len += sprintf(buf + len, "%s",         \
113                                 table[i].name);                 \
114                         break;                                  \
115                 }                                               \
116         }                                                       \
117         len += sprintf(buf + len, "\n");                        \
118         return len;                                             \
119 }
120
121 static struct {
122         u32             value;
123         char            *name;
124 } sas_device_type_names[] = {
125         { SAS_PHY_UNUSED,               "unused" },
126         { SAS_END_DEVICE,               "end device" },
127         { SAS_EDGE_EXPANDER_DEVICE,     "edge expander" },
128         { SAS_FANOUT_EXPANDER_DEVICE,   "fanout expander" },
129 };
130 sas_bitfield_name_search(device_type, sas_device_type_names)
131
132
133 static struct {
134         u32             value;
135         char            *name;
136 } sas_protocol_names[] = {
137         { SAS_PROTOCOL_SATA,            "sata" },
138         { SAS_PROTOCOL_SMP,             "smp" },
139         { SAS_PROTOCOL_STP,             "stp" },
140         { SAS_PROTOCOL_SSP,             "ssp" },
141 };
142 sas_bitfield_name_match(protocol, sas_protocol_names)
143
144 static struct {
145         u32             value;
146         char            *name;
147 } sas_linkspeed_names[] = {
148         { SAS_LINK_RATE_UNKNOWN,        "Unknown" },
149         { SAS_PHY_DISABLED,             "Phy disabled" },
150         { SAS_LINK_RATE_FAILED,         "Link Rate failed" },
151         { SAS_SATA_SPINUP_HOLD,         "Spin-up hold" },
152         { SAS_LINK_RATE_1_5_GBPS,       "1.5 Gbit" },
153         { SAS_LINK_RATE_3_0_GBPS,       "3.0 Gbit" },
154         { SAS_LINK_RATE_6_0_GBPS,       "6.0 Gbit" },
155         { SAS_LINK_RATE_12_0_GBPS,      "12.0 Gbit" },
156 };
157 sas_bitfield_name_search(linkspeed, sas_linkspeed_names)
158 sas_bitfield_name_set(linkspeed, sas_linkspeed_names)
159
160 static struct sas_end_device *sas_sdev_to_rdev(struct scsi_device *sdev)
161 {
162         struct sas_rphy *rphy = target_to_rphy(sdev->sdev_target);
163         struct sas_end_device *rdev;
164
165         BUG_ON(rphy->identify.device_type != SAS_END_DEVICE);
166
167         rdev = rphy_to_end_device(rphy);
168         return rdev;
169 }
170
171 static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
172                             struct sas_rphy *rphy)
173 {
174         struct request *req;
175         int ret;
176         int (*handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);
177
178         while ((req = blk_fetch_request(q)) != NULL) {
179                 spin_unlock_irq(q->queue_lock);
180
181                 scsi_req(req)->resid_len = blk_rq_bytes(req);
182                 if (req->next_rq)
183                         scsi_req(req->next_rq)->resid_len =
184                                 blk_rq_bytes(req->next_rq);
185                 handler = to_sas_internal(shost->transportt)->f->smp_handler;
186                 ret = handler(shost, rphy, req);
187                 req->errors = ret;
188
189                 blk_end_request_all(req, ret);
190
191                 spin_lock_irq(q->queue_lock);
192         }
193 }
194
195 static void sas_host_smp_request(struct request_queue *q)
196 {
197         sas_smp_request(q, (struct Scsi_Host *)q->queuedata, NULL);
198 }
199
200 static void sas_non_host_smp_request(struct request_queue *q)
201 {
202         struct sas_rphy *rphy = q->queuedata;
203         sas_smp_request(q, rphy_to_shost(rphy), rphy);
204 }
205
206 static void sas_host_release(struct device *dev)
207 {
208         struct Scsi_Host *shost = dev_to_shost(dev);
209         struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
210         struct request_queue *q = sas_host->q;
211
212         if (q)
213                 blk_cleanup_queue(q);
214 }
215
216 static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
217 {
218         struct request_queue *q;
219         int error;
220         struct device *dev;
221         char namebuf[20];
222         const char *name;
223         void (*release)(struct device *);
224
225         if (!to_sas_internal(shost->transportt)->f->smp_handler) {
226                 printk("%s can't handle SMP requests\n", shost->hostt->name);
227                 return 0;
228         }
229
230         if (rphy) {
231                 q = blk_init_queue(sas_non_host_smp_request, NULL);
232                 dev = &rphy->dev;
233                 name = dev_name(dev);
234                 release = NULL;
235         } else {
236                 q = blk_init_queue(sas_host_smp_request, NULL);
237                 dev = &shost->shost_gendev;
238                 snprintf(namebuf, sizeof(namebuf),
239                          "sas_host%d", shost->host_no);
240                 name = namebuf;
241                 release = sas_host_release;
242         }
243         if (!q)
244                 return -ENOMEM;
245
246         error = bsg_register_queue(q, dev, name, release);
247         if (error) {
248                 blk_cleanup_queue(q);
249                 return -ENOMEM;
250         }
251
252         if (rphy)
253                 rphy->q = q;
254         else
255                 to_sas_host_attrs(shost)->q = q;
256
257         if (rphy)
258                 q->queuedata = rphy;
259         else
260                 q->queuedata = shost;
261
262         queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
263         return 0;
264 }
265
266 static void sas_bsg_remove(struct Scsi_Host *shost, struct sas_rphy *rphy)
267 {
268         struct request_queue *q;
269
270         if (rphy)
271                 q = rphy->q;
272         else
273                 q = to_sas_host_attrs(shost)->q;
274
275         if (!q)
276                 return;
277
278         bsg_unregister_queue(q);
279 }
280
281 /*
282  * SAS host attributes
283  */
284
285 static int sas_host_setup(struct transport_container *tc, struct device *dev,
286                           struct device *cdev)
287 {
288         struct Scsi_Host *shost = dev_to_shost(dev);
289         struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
290
291         INIT_LIST_HEAD(&sas_host->rphy_list);
292         mutex_init(&sas_host->lock);
293         sas_host->next_target_id = 0;
294         sas_host->next_expander_id = 0;
295         sas_host->next_port_id = 0;
296
297         if (sas_bsg_initialize(shost, NULL))
298                 dev_printk(KERN_ERR, dev, "fail to a bsg device %d\n",
299                            shost->host_no);
300
301         return 0;
302 }
303
304 static int sas_host_remove(struct transport_container *tc, struct device *dev,
305                            struct device *cdev)
306 {
307         struct Scsi_Host *shost = dev_to_shost(dev);
308
309         sas_bsg_remove(shost, NULL);
310
311         return 0;
312 }
313
314 static DECLARE_TRANSPORT_CLASS(sas_host_class,
315                 "sas_host", sas_host_setup, sas_host_remove, NULL);
316
317 static int sas_host_match(struct attribute_container *cont,
318                             struct device *dev)
319 {
320         struct Scsi_Host *shost;
321         struct sas_internal *i;
322
323         if (!scsi_is_host_device(dev))
324                 return 0;
325         shost = dev_to_shost(dev);
326
327         if (!shost->transportt)
328                 return 0;
329         if (shost->transportt->host_attrs.ac.class !=
330                         &sas_host_class.class)
331                 return 0;
332
333         i = to_sas_internal(shost->transportt);
334         return &i->t.host_attrs.ac == cont;
335 }
336
337 static int do_sas_phy_delete(struct device *dev, void *data)
338 {
339         int pass = (int)(unsigned long)data;
340
341         if (pass == 0 && scsi_is_sas_port(dev))
342                 sas_port_delete(dev_to_sas_port(dev));
343         else if (pass == 1 && scsi_is_sas_phy(dev))
344                 sas_phy_delete(dev_to_phy(dev));
345         return 0;
346 }
347
348 /**
349  * sas_remove_children  -  tear down a devices SAS data structures
350  * @dev:        device belonging to the sas object
351  *
352  * Removes all SAS PHYs and remote PHYs for a given object
353  */
354 void sas_remove_children(struct device *dev)
355 {
356         device_for_each_child(dev, (void *)0, do_sas_phy_delete);
357         device_for_each_child(dev, (void *)1, do_sas_phy_delete);
358 }
359 EXPORT_SYMBOL(sas_remove_children);
360
361 /**
362  * sas_remove_host  -  tear down a Scsi_Host's SAS data structures
363  * @shost:      Scsi Host that is torn down
364  *
365  * Removes all SAS PHYs and remote PHYs for a given Scsi_Host.
366  * Must be called just before scsi_remove_host for SAS HBAs.
367  */
368 void sas_remove_host(struct Scsi_Host *shost)
369 {
370         sas_remove_children(&shost->shost_gendev);
371 }
372 EXPORT_SYMBOL(sas_remove_host);
373
374 /**
375  * sas_get_address - return the SAS address of the device
376  * @sdev: scsi device
377  *
378  * Returns the SAS address of the scsi device
379  */
380 u64 sas_get_address(struct scsi_device *sdev)
381 {
382         struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
383
384         return rdev->rphy.identify.sas_address;
385 }
386 EXPORT_SYMBOL(sas_get_address);
387
388 /**
389  * sas_tlr_supported - checking TLR bit in vpd 0x90
390  * @sdev: scsi device struct
391  *
392  * Check Transport Layer Retries are supported or not.
393  * If vpd page 0x90 is present, TRL is supported.
394  *
395  */
396 unsigned int
397 sas_tlr_supported(struct scsi_device *sdev)
398 {
399         const int vpd_len = 32;
400         struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
401         char *buffer = kzalloc(vpd_len, GFP_KERNEL);
402         int ret = 0;
403
404         if (scsi_get_vpd_page(sdev, 0x90, buffer, vpd_len))
405                 goto out;
406
407         /*
408          * Magic numbers: the VPD Protocol page (0x90)
409          * has a 4 byte header and then one entry per device port
410          * the TLR bit is at offset 8 on each port entry
411          * if we take the first port, that's at total offset 12
412          */
413         ret = buffer[12] & 0x01;
414
415  out:
416         kfree(buffer);
417         rdev->tlr_supported = ret;
418         return ret;
419
420 }
421 EXPORT_SYMBOL_GPL(sas_tlr_supported);
422
423 /**
424  * sas_disable_tlr - setting TLR flags
425  * @sdev: scsi device struct
426  *
427  * Seting tlr_enabled flag to 0.
428  *
429  */
430 void
431 sas_disable_tlr(struct scsi_device *sdev)
432 {
433         struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
434
435         rdev->tlr_enabled = 0;
436 }
437 EXPORT_SYMBOL_GPL(sas_disable_tlr);
438
439 /**
440  * sas_enable_tlr - setting TLR flags
441  * @sdev: scsi device struct
442  *
443  * Seting tlr_enabled flag 1.
444  *
445  */
446 void sas_enable_tlr(struct scsi_device *sdev)
447 {
448         unsigned int tlr_supported = 0;
449         tlr_supported  = sas_tlr_supported(sdev);
450
451         if (tlr_supported) {
452                 struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
453
454                 rdev->tlr_enabled = 1;
455         }
456
457         return;
458 }
459 EXPORT_SYMBOL_GPL(sas_enable_tlr);
460
461 unsigned int sas_is_tlr_enabled(struct scsi_device *sdev)
462 {
463         struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
464         return rdev->tlr_enabled;
465 }
466 EXPORT_SYMBOL_GPL(sas_is_tlr_enabled);
467
468 /*
469  * SAS Phy attributes
470  */
471
472 #define sas_phy_show_simple(field, name, format_string, cast)           \
473 static ssize_t                                                          \
474 show_sas_phy_##name(struct device *dev,                                 \
475                     struct device_attribute *attr, char *buf)           \
476 {                                                                       \
477         struct sas_phy *phy = transport_class_to_phy(dev);              \
478                                                                         \
479         return snprintf(buf, 20, format_string, cast phy->field);       \
480 }
481
482 #define sas_phy_simple_attr(field, name, format_string, type)           \
483         sas_phy_show_simple(field, name, format_string, (type)) \
484 static DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL)
485
486 #define sas_phy_show_protocol(field, name)                              \
487 static ssize_t                                                          \
488 show_sas_phy_##name(struct device *dev,                                 \
489                     struct device_attribute *attr, char *buf)           \
490 {                                                                       \
491         struct sas_phy *phy = transport_class_to_phy(dev);              \
492                                                                         \
493         if (!phy->field)                                                \
494                 return snprintf(buf, 20, "none\n");                     \
495         return get_sas_protocol_names(phy->field, buf);         \
496 }
497
498 #define sas_phy_protocol_attr(field, name)                              \
499         sas_phy_show_protocol(field, name)                              \
500 static DEVICE_ATTR(name, S_IRUGO, show_sas_phy_##name, NULL)
501
502 #define sas_phy_show_linkspeed(field)                                   \
503 static ssize_t                                                          \
504 show_sas_phy_##field(struct device *dev,                                \
505                      struct device_attribute *attr, char *buf)          \
506 {                                                                       \
507         struct sas_phy *phy = transport_class_to_phy(dev);              \
508                                                                         \
509         return get_sas_linkspeed_names(phy->field, buf);                \
510 }
511
512 /* Fudge to tell if we're minimum or maximum */
513 #define sas_phy_store_linkspeed(field)                                  \
514 static ssize_t                                                          \
515 store_sas_phy_##field(struct device *dev,                               \
516                       struct device_attribute *attr,                    \
517                       const char *buf,  size_t count)                   \
518 {                                                                       \
519         struct sas_phy *phy = transport_class_to_phy(dev);              \
520         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);        \
521         struct sas_internal *i = to_sas_internal(shost->transportt);    \
522         u32 value;                                                      \
523         struct sas_phy_linkrates rates = {0};                           \
524         int error;                                                      \
525                                                                         \
526         error = set_sas_linkspeed_names(&value, buf);                   \
527         if (error)                                                      \
528                 return error;                                           \
529         rates.field = value;                                            \
530         error = i->f->set_phy_speed(phy, &rates);                       \
531                                                                         \
532         return error ? error : count;                                   \
533 }
534
535 #define sas_phy_linkspeed_rw_attr(field)                                \
536         sas_phy_show_linkspeed(field)                                   \
537         sas_phy_store_linkspeed(field)                                  \
538 static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field,                \
539         store_sas_phy_##field)
540
541 #define sas_phy_linkspeed_attr(field)                                   \
542         sas_phy_show_linkspeed(field)                                   \
543 static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)
544
545
546 #define sas_phy_show_linkerror(field)                                   \
547 static ssize_t                                                          \
548 show_sas_phy_##field(struct device *dev,                                \
549                      struct device_attribute *attr, char *buf)          \
550 {                                                                       \
551         struct sas_phy *phy = transport_class_to_phy(dev);              \
552         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);        \
553         struct sas_internal *i = to_sas_internal(shost->transportt);    \
554         int error;                                                      \
555                                                                         \
556         error = i->f->get_linkerrors ? i->f->get_linkerrors(phy) : 0;   \
557         if (error)                                                      \
558                 return error;                                           \
559         return snprintf(buf, 20, "%u\n", phy->field);                   \
560 }
561
562 #define sas_phy_linkerror_attr(field)                                   \
563         sas_phy_show_linkerror(field)                                   \
564 static DEVICE_ATTR(field, S_IRUGO, show_sas_phy_##field, NULL)
565
566
567 static ssize_t
568 show_sas_device_type(struct device *dev,
569                      struct device_attribute *attr, char *buf)
570 {
571         struct sas_phy *phy = transport_class_to_phy(dev);
572
573         if (!phy->identify.device_type)
574                 return snprintf(buf, 20, "none\n");
575         return get_sas_device_type_names(phy->identify.device_type, buf);
576 }
577 static DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);
578
579 static ssize_t do_sas_phy_enable(struct device *dev,
580                 size_t count, int enable)
581 {
582         struct sas_phy *phy = transport_class_to_phy(dev);
583         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
584         struct sas_internal *i = to_sas_internal(shost->transportt);
585         int error;
586
587         error = i->f->phy_enable(phy, enable);
588         if (error)
589                 return error;
590         phy->enabled = enable;
591         return count;
592 };
593
594 static ssize_t
595 store_sas_phy_enable(struct device *dev, struct device_attribute *attr,
596                      const char *buf, size_t count)
597 {
598         if (count < 1)
599                 return -EINVAL;
600
601         switch (buf[0]) {
602         case '0':
603                 do_sas_phy_enable(dev, count, 0);
604                 break;
605         case '1':
606                 do_sas_phy_enable(dev, count, 1);
607                 break;
608         default:
609                 return -EINVAL;
610         }
611
612         return count;
613 }
614
615 static ssize_t
616 show_sas_phy_enable(struct device *dev, struct device_attribute *attr,
617                     char *buf)
618 {
619         struct sas_phy *phy = transport_class_to_phy(dev);
620
621         return snprintf(buf, 20, "%d", phy->enabled);
622 }
623
624 static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, show_sas_phy_enable,
625                          store_sas_phy_enable);
626
627 static ssize_t
628 do_sas_phy_reset(struct device *dev, size_t count, int hard_reset)
629 {
630         struct sas_phy *phy = transport_class_to_phy(dev);
631         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
632         struct sas_internal *i = to_sas_internal(shost->transportt);
633         int error;
634
635         error = i->f->phy_reset(phy, hard_reset);
636         if (error)
637                 return error;
638         phy->enabled = 1;
639         return count;
640 };
641
642 static ssize_t
643 store_sas_link_reset(struct device *dev, struct device_attribute *attr,
644                      const char *buf, size_t count)
645 {
646         return do_sas_phy_reset(dev, count, 0);
647 }
648 static DEVICE_ATTR(link_reset, S_IWUSR, NULL, store_sas_link_reset);
649
650 static ssize_t
651 store_sas_hard_reset(struct device *dev, struct device_attribute *attr,
652                      const char *buf, size_t count)
653 {
654         return do_sas_phy_reset(dev, count, 1);
655 }
656 static DEVICE_ATTR(hard_reset, S_IWUSR, NULL, store_sas_hard_reset);
657
658 sas_phy_protocol_attr(identify.initiator_port_protocols,
659                 initiator_port_protocols);
660 sas_phy_protocol_attr(identify.target_port_protocols,
661                 target_port_protocols);
662 sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
663                 unsigned long long);
664 sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
665 //sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int);
666 sas_phy_linkspeed_attr(negotiated_linkrate);
667 sas_phy_linkspeed_attr(minimum_linkrate_hw);
668 sas_phy_linkspeed_rw_attr(minimum_linkrate);
669 sas_phy_linkspeed_attr(maximum_linkrate_hw);
670 sas_phy_linkspeed_rw_attr(maximum_linkrate);
671 sas_phy_linkerror_attr(invalid_dword_count);
672 sas_phy_linkerror_attr(running_disparity_error_count);
673 sas_phy_linkerror_attr(loss_of_dword_sync_count);
674 sas_phy_linkerror_attr(phy_reset_problem_count);
675
676 static int sas_phy_setup(struct transport_container *tc, struct device *dev,
677                          struct device *cdev)
678 {
679         struct sas_phy *phy = dev_to_phy(dev);
680         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
681         struct sas_internal *i = to_sas_internal(shost->transportt);
682
683         if (i->f->phy_setup)
684                 i->f->phy_setup(phy);
685
686         return 0;
687 }
688
689 static DECLARE_TRANSPORT_CLASS(sas_phy_class,
690                 "sas_phy", sas_phy_setup, NULL, NULL);
691
692 static int sas_phy_match(struct attribute_container *cont, struct device *dev)
693 {
694         struct Scsi_Host *shost;
695         struct sas_internal *i;
696
697         if (!scsi_is_sas_phy(dev))
698                 return 0;
699         shost = dev_to_shost(dev->parent);
700
701         if (!shost->transportt)
702                 return 0;
703         if (shost->transportt->host_attrs.ac.class !=
704                         &sas_host_class.class)
705                 return 0;
706
707         i = to_sas_internal(shost->transportt);
708         return &i->phy_attr_cont.ac == cont;
709 }
710
711 static void sas_phy_release(struct device *dev)
712 {
713         struct sas_phy *phy = dev_to_phy(dev);
714         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
715         struct sas_internal *i = to_sas_internal(shost->transportt);
716
717         if (i->f->phy_release)
718                 i->f->phy_release(phy);
719         put_device(dev->parent);
720         kfree(phy);
721 }
722
723 /**
724  * sas_phy_alloc  -  allocates and initialize a SAS PHY structure
725  * @parent:     Parent device
726  * @number:     Phy index
727  *
728  * Allocates an SAS PHY structure.  It will be added in the device tree
729  * below the device specified by @parent, which has to be either a Scsi_Host
730  * or sas_rphy.
731  *
732  * Returns:
733  *      SAS PHY allocated or %NULL if the allocation failed.
734  */
735 struct sas_phy *sas_phy_alloc(struct device *parent, int number)
736 {
737         struct Scsi_Host *shost = dev_to_shost(parent);
738         struct sas_phy *phy;
739
740         phy = kzalloc(sizeof(*phy), GFP_KERNEL);
741         if (!phy)
742                 return NULL;
743
744         phy->number = number;
745         phy->enabled = 1;
746
747         device_initialize(&phy->dev);
748         phy->dev.parent = get_device(parent);
749         phy->dev.release = sas_phy_release;
750         INIT_LIST_HEAD(&phy->port_siblings);
751         if (scsi_is_sas_expander_device(parent)) {
752                 struct sas_rphy *rphy = dev_to_rphy(parent);
753                 dev_set_name(&phy->dev, "phy-%d:%d:%d", shost->host_no,
754                         rphy->scsi_target_id, number);
755         } else
756                 dev_set_name(&phy->dev, "phy-%d:%d", shost->host_no, number);
757
758         transport_setup_device(&phy->dev);
759
760         return phy;
761 }
762 EXPORT_SYMBOL(sas_phy_alloc);
763
764 /**
765  * sas_phy_add  -  add a SAS PHY to the device hierarchy
766  * @phy:        The PHY to be added
767  *
768  * Publishes a SAS PHY to the rest of the system.
769  */
770 int sas_phy_add(struct sas_phy *phy)
771 {
772         int error;
773
774         error = device_add(&phy->dev);
775         if (!error) {
776                 transport_add_device(&phy->dev);
777                 transport_configure_device(&phy->dev);
778         }
779
780         return error;
781 }
782 EXPORT_SYMBOL(sas_phy_add);
783
784 /**
785  * sas_phy_free  -  free a SAS PHY
786  * @phy:        SAS PHY to free
787  *
788  * Frees the specified SAS PHY.
789  *
790  * Note:
791  *   This function must only be called on a PHY that has not
792  *   successfully been added using sas_phy_add().
793  */
794 void sas_phy_free(struct sas_phy *phy)
795 {
796         transport_destroy_device(&phy->dev);
797         put_device(&phy->dev);
798 }
799 EXPORT_SYMBOL(sas_phy_free);
800
801 /**
802  * sas_phy_delete  -  remove SAS PHY
803  * @phy:        SAS PHY to remove
804  *
805  * Removes the specified SAS PHY.  If the SAS PHY has an
806  * associated remote PHY it is removed before.
807  */
808 void
809 sas_phy_delete(struct sas_phy *phy)
810 {
811         struct device *dev = &phy->dev;
812
813         /* this happens if the phy is still part of a port when deleted */
814         BUG_ON(!list_empty(&phy->port_siblings));
815
816         transport_remove_device(dev);
817         device_del(dev);
818         transport_destroy_device(dev);
819         put_device(dev);
820 }
821 EXPORT_SYMBOL(sas_phy_delete);
822
823 /**
824  * scsi_is_sas_phy  -  check if a struct device represents a SAS PHY
825  * @dev:        device to check
826  *
827  * Returns:
828  *      %1 if the device represents a SAS PHY, %0 else
829  */
830 int scsi_is_sas_phy(const struct device *dev)
831 {
832         return dev->release == sas_phy_release;
833 }
834 EXPORT_SYMBOL(scsi_is_sas_phy);
835
836 /*
837  * SAS Port attributes
838  */
839 #define sas_port_show_simple(field, name, format_string, cast)          \
840 static ssize_t                                                          \
841 show_sas_port_##name(struct device *dev,                                \
842                      struct device_attribute *attr, char *buf)          \
843 {                                                                       \
844         struct sas_port *port = transport_class_to_sas_port(dev);       \
845                                                                         \
846         return snprintf(buf, 20, format_string, cast port->field);      \
847 }
848
849 #define sas_port_simple_attr(field, name, format_string, type)          \
850         sas_port_show_simple(field, name, format_string, (type))        \
851 static DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL)
852
853 sas_port_simple_attr(num_phys, num_phys, "%d\n", int);
854
855 static DECLARE_TRANSPORT_CLASS(sas_port_class,
856                                "sas_port", NULL, NULL, NULL);
857
858 static int sas_port_match(struct attribute_container *cont, struct device *dev)
859 {
860         struct Scsi_Host *shost;
861         struct sas_internal *i;
862
863         if (!scsi_is_sas_port(dev))
864                 return 0;
865         shost = dev_to_shost(dev->parent);
866
867         if (!shost->transportt)
868                 return 0;
869         if (shost->transportt->host_attrs.ac.class !=
870                         &sas_host_class.class)
871                 return 0;
872
873         i = to_sas_internal(shost->transportt);
874         return &i->port_attr_cont.ac == cont;
875 }
876
877
878 static void sas_port_release(struct device *dev)
879 {
880         struct sas_port *port = dev_to_sas_port(dev);
881
882         BUG_ON(!list_empty(&port->phy_list));
883
884         put_device(dev->parent);
885         kfree(port);
886 }
887
888 static void sas_port_create_link(struct sas_port *port,
889                                  struct sas_phy *phy)
890 {
891         int res;
892
893         res = sysfs_create_link(&port->dev.kobj, &phy->dev.kobj,
894                                 dev_name(&phy->dev));
895         if (res)
896                 goto err;
897         res = sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port");
898         if (res)
899                 goto err;
900         return;
901 err:
902         printk(KERN_ERR "%s: Cannot create port links, err=%d\n",
903                __func__, res);
904 }
905
906 static void sas_port_delete_link(struct sas_port *port,
907                                  struct sas_phy *phy)
908 {
909         sysfs_remove_link(&port->dev.kobj, dev_name(&phy->dev));
910         sysfs_remove_link(&phy->dev.kobj, "port");
911 }
912
913 /** sas_port_alloc - allocate and initialize a SAS port structure
914  *
915  * @parent:     parent device
916  * @port_id:    port number
917  *
918  * Allocates a SAS port structure.  It will be added to the device tree
919  * below the device specified by @parent which must be either a Scsi_Host
920  * or a sas_expander_device.
921  *
922  * Returns %NULL on error
923  */
924 struct sas_port *sas_port_alloc(struct device *parent, int port_id)
925 {
926         struct Scsi_Host *shost = dev_to_shost(parent);
927         struct sas_port *port;
928
929         port = kzalloc(sizeof(*port), GFP_KERNEL);
930         if (!port)
931                 return NULL;
932
933         port->port_identifier = port_id;
934
935         device_initialize(&port->dev);
936
937         port->dev.parent = get_device(parent);
938         port->dev.release = sas_port_release;
939
940         mutex_init(&port->phy_list_mutex);
941         INIT_LIST_HEAD(&port->phy_list);
942
943         if (scsi_is_sas_expander_device(parent)) {
944                 struct sas_rphy *rphy = dev_to_rphy(parent);
945                 dev_set_name(&port->dev, "port-%d:%d:%d", shost->host_no,
946                              rphy->scsi_target_id, port->port_identifier);
947         } else
948                 dev_set_name(&port->dev, "port-%d:%d", shost->host_no,
949                              port->port_identifier);
950
951         transport_setup_device(&port->dev);
952
953         return port;
954 }
955 EXPORT_SYMBOL(sas_port_alloc);
956
957 /** sas_port_alloc_num - allocate and initialize a SAS port structure
958  *
959  * @parent:     parent device
960  *
961  * Allocates a SAS port structure and a number to go with it.  This
962  * interface is really for adapters where the port number has no
963  * meansing, so the sas class should manage them.  It will be added to
964  * the device tree below the device specified by @parent which must be
965  * either a Scsi_Host or a sas_expander_device.
966  *
967  * Returns %NULL on error
968  */
969 struct sas_port *sas_port_alloc_num(struct device *parent)
970 {
971         int index;
972         struct Scsi_Host *shost = dev_to_shost(parent);
973         struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
974
975         /* FIXME: use idr for this eventually */
976         mutex_lock(&sas_host->lock);
977         if (scsi_is_sas_expander_device(parent)) {
978                 struct sas_rphy *rphy = dev_to_rphy(parent);
979                 struct sas_expander_device *exp = rphy_to_expander_device(rphy);
980
981                 index = exp->next_port_id++;
982         } else
983                 index = sas_host->next_port_id++;
984         mutex_unlock(&sas_host->lock);
985         return sas_port_alloc(parent, index);
986 }
987 EXPORT_SYMBOL(sas_port_alloc_num);
988
989 /**
990  * sas_port_add - add a SAS port to the device hierarchy
991  * @port:       port to be added
992  *
993  * publishes a port to the rest of the system
994  */
995 int sas_port_add(struct sas_port *port)
996 {
997         int error;
998
999         /* No phys should be added until this is made visible */
1000         BUG_ON(!list_empty(&port->phy_list));
1001
1002         error = device_add(&port->dev);
1003
1004         if (error)
1005                 return error;
1006
1007         transport_add_device(&port->dev);
1008         transport_configure_device(&port->dev);
1009
1010         return 0;
1011 }
1012 EXPORT_SYMBOL(sas_port_add);
1013
1014 /**
1015  * sas_port_free  -  free a SAS PORT
1016  * @port:       SAS PORT to free
1017  *
1018  * Frees the specified SAS PORT.
1019  *
1020  * Note:
1021  *   This function must only be called on a PORT that has not
1022  *   successfully been added using sas_port_add().
1023  */
1024 void sas_port_free(struct sas_port *port)
1025 {
1026         transport_destroy_device(&port->dev);
1027         put_device(&port->dev);
1028 }
1029 EXPORT_SYMBOL(sas_port_free);
1030
1031 /**
1032  * sas_port_delete  -  remove SAS PORT
1033  * @port:       SAS PORT to remove
1034  *
1035  * Removes the specified SAS PORT.  If the SAS PORT has an
1036  * associated phys, unlink them from the port as well.
1037  */
1038 void sas_port_delete(struct sas_port *port)
1039 {
1040         struct device *dev = &port->dev;
1041         struct sas_phy *phy, *tmp_phy;
1042
1043         if (port->rphy) {
1044                 sas_rphy_delete(port->rphy);
1045                 port->rphy = NULL;
1046         }
1047
1048         mutex_lock(&port->phy_list_mutex);
1049         list_for_each_entry_safe(phy, tmp_phy, &port->phy_list,
1050                                  port_siblings) {
1051                 sas_port_delete_link(port, phy);
1052                 list_del_init(&phy->port_siblings);
1053         }
1054         mutex_unlock(&port->phy_list_mutex);
1055
1056         if (port->is_backlink) {
1057                 struct device *parent = port->dev.parent;
1058
1059                 sysfs_remove_link(&port->dev.kobj, dev_name(parent));
1060                 port->is_backlink = 0;
1061         }
1062
1063         transport_remove_device(dev);
1064         device_del(dev);
1065         transport_destroy_device(dev);
1066         put_device(dev);
1067 }
1068 EXPORT_SYMBOL(sas_port_delete);
1069
1070 /**
1071  * scsi_is_sas_port -  check if a struct device represents a SAS port
1072  * @dev:        device to check
1073  *
1074  * Returns:
1075  *      %1 if the device represents a SAS Port, %0 else
1076  */
1077 int scsi_is_sas_port(const struct device *dev)
1078 {
1079         return dev->release == sas_port_release;
1080 }
1081 EXPORT_SYMBOL(scsi_is_sas_port);
1082
1083 /**
1084  * sas_port_get_phy - try to take a reference on a port member
1085  * @port: port to check
1086  */
1087 struct sas_phy *sas_port_get_phy(struct sas_port *port)
1088 {
1089         struct sas_phy *phy;
1090
1091         mutex_lock(&port->phy_list_mutex);
1092         if (list_empty(&port->phy_list))
1093                 phy = NULL;
1094         else {
1095                 struct list_head *ent = port->phy_list.next;
1096
1097                 phy = list_entry(ent, typeof(*phy), port_siblings);
1098                 get_device(&phy->dev);
1099         }
1100         mutex_unlock(&port->phy_list_mutex);
1101
1102         return phy;
1103 }
1104 EXPORT_SYMBOL(sas_port_get_phy);
1105
1106 /**
1107  * sas_port_add_phy - add another phy to a port to form a wide port
1108  * @port:       port to add the phy to
1109  * @phy:        phy to add
1110  *
1111  * When a port is initially created, it is empty (has no phys).  All
1112  * ports must have at least one phy to operated, and all wide ports
1113  * must have at least two.  The current code makes no difference
1114  * between ports and wide ports, but the only object that can be
1115  * connected to a remote device is a port, so ports must be formed on
1116  * all devices with phys if they're connected to anything.
1117  */
1118 void sas_port_add_phy(struct sas_port *port, struct sas_phy *phy)
1119 {
1120         mutex_lock(&port->phy_list_mutex);
1121         if (unlikely(!list_empty(&phy->port_siblings))) {
1122                 /* make sure we're already on this port */
1123                 struct sas_phy *tmp;
1124
1125                 list_for_each_entry(tmp, &port->phy_list, port_siblings)
1126                         if (tmp == phy)
1127                                 break;
1128                 /* If this trips, you added a phy that was already
1129                  * part of a different port */
1130                 if (unlikely(tmp != phy)) {
1131                         dev_printk(KERN_ERR, &port->dev, "trying to add phy %s fails: it's already part of another port\n",
1132                                    dev_name(&phy->dev));
1133                         BUG();
1134                 }
1135         } else {
1136                 sas_port_create_link(port, phy);
1137                 list_add_tail(&phy->port_siblings, &port->phy_list);
1138                 port->num_phys++;
1139         }
1140         mutex_unlock(&port->phy_list_mutex);
1141 }
1142 EXPORT_SYMBOL(sas_port_add_phy);
1143
1144 /**
1145  * sas_port_delete_phy - remove a phy from a port or wide port
1146  * @port:       port to remove the phy from
1147  * @phy:        phy to remove
1148  *
1149  * This operation is used for tearing down ports again.  It must be
1150  * done to every port or wide port before calling sas_port_delete.
1151  */
1152 void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy)
1153 {
1154         mutex_lock(&port->phy_list_mutex);
1155         sas_port_delete_link(port, phy);
1156         list_del_init(&phy->port_siblings);
1157         port->num_phys--;
1158         mutex_unlock(&port->phy_list_mutex);
1159 }
1160 EXPORT_SYMBOL(sas_port_delete_phy);
1161
1162 void sas_port_mark_backlink(struct sas_port *port)
1163 {
1164         int res;
1165         struct device *parent = port->dev.parent->parent->parent;
1166
1167         if (port->is_backlink)
1168                 return;
1169         port->is_backlink = 1;
1170         res = sysfs_create_link(&port->dev.kobj, &parent->kobj,
1171                                 dev_name(parent));
1172         if (res)
1173                 goto err;
1174         return;
1175 err:
1176         printk(KERN_ERR "%s: Cannot create port backlink, err=%d\n",
1177                __func__, res);
1178
1179 }
1180 EXPORT_SYMBOL(sas_port_mark_backlink);
1181
1182 /*
1183  * SAS remote PHY attributes.
1184  */
1185
1186 #define sas_rphy_show_simple(field, name, format_string, cast)          \
1187 static ssize_t                                                          \
1188 show_sas_rphy_##name(struct device *dev,                                \
1189                      struct device_attribute *attr, char *buf)          \
1190 {                                                                       \
1191         struct sas_rphy *rphy = transport_class_to_rphy(dev);           \
1192                                                                         \
1193         return snprintf(buf, 20, format_string, cast rphy->field);      \
1194 }
1195
1196 #define sas_rphy_simple_attr(field, name, format_string, type)          \
1197         sas_rphy_show_simple(field, name, format_string, (type))        \
1198 static SAS_DEVICE_ATTR(rphy, name, S_IRUGO,                     \
1199                 show_sas_rphy_##name, NULL)
1200
1201 #define sas_rphy_show_protocol(field, name)                             \
1202 static ssize_t                                                          \
1203 show_sas_rphy_##name(struct device *dev,                                \
1204                      struct device_attribute *attr, char *buf)          \
1205 {                                                                       \
1206         struct sas_rphy *rphy = transport_class_to_rphy(dev);           \
1207                                                                         \
1208         if (!rphy->field)                                       \
1209                 return snprintf(buf, 20, "none\n");                     \
1210         return get_sas_protocol_names(rphy->field, buf);        \
1211 }
1212
1213 #define sas_rphy_protocol_attr(field, name)                             \
1214         sas_rphy_show_protocol(field, name)                             \
1215 static SAS_DEVICE_ATTR(rphy, name, S_IRUGO,                     \
1216                 show_sas_rphy_##name, NULL)
1217
1218 static ssize_t
1219 show_sas_rphy_device_type(struct device *dev,
1220                           struct device_attribute *attr, char *buf)
1221 {
1222         struct sas_rphy *rphy = transport_class_to_rphy(dev);
1223
1224         if (!rphy->identify.device_type)
1225                 return snprintf(buf, 20, "none\n");
1226         return get_sas_device_type_names(
1227                         rphy->identify.device_type, buf);
1228 }
1229
1230 static SAS_DEVICE_ATTR(rphy, device_type, S_IRUGO,
1231                 show_sas_rphy_device_type, NULL);
1232
1233 static ssize_t
1234 show_sas_rphy_enclosure_identifier(struct device *dev,
1235                                    struct device_attribute *attr, char *buf)
1236 {
1237         struct sas_rphy *rphy = transport_class_to_rphy(dev);
1238         struct sas_phy *phy = dev_to_phy(rphy->dev.parent);
1239         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
1240         struct sas_internal *i = to_sas_internal(shost->transportt);
1241         u64 identifier;
1242         int error;
1243
1244         error = i->f->get_enclosure_identifier(rphy, &identifier);
1245         if (error)
1246                 return error;
1247         return sprintf(buf, "0x%llx\n", (unsigned long long)identifier);
1248 }
1249
1250 static SAS_DEVICE_ATTR(rphy, enclosure_identifier, S_IRUGO,
1251                 show_sas_rphy_enclosure_identifier, NULL);
1252
1253 static ssize_t
1254 show_sas_rphy_bay_identifier(struct device *dev,
1255                              struct device_attribute *attr, char *buf)
1256 {
1257         struct sas_rphy *rphy = transport_class_to_rphy(dev);
1258         struct sas_phy *phy = dev_to_phy(rphy->dev.parent);
1259         struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
1260         struct sas_internal *i = to_sas_internal(shost->transportt);
1261         int val;
1262
1263         val = i->f->get_bay_identifier(rphy);
1264         if (val < 0)
1265                 return val;
1266         return sprintf(buf, "%d\n", val);
1267 }
1268
1269 static SAS_DEVICE_ATTR(rphy, bay_identifier, S_IRUGO,
1270                 show_sas_rphy_bay_identifier, NULL);
1271
1272 sas_rphy_protocol_attr(identify.initiator_port_protocols,
1273                 initiator_port_protocols);
1274 sas_rphy_protocol_attr(identify.target_port_protocols, target_port_protocols);
1275 sas_rphy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n",
1276                 unsigned long long);
1277 sas_rphy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8);
1278 sas_rphy_simple_attr(scsi_target_id, scsi_target_id, "%d\n", u32);
1279
1280 /* only need 8 bytes of data plus header (4 or 8) */
1281 #define BUF_SIZE 64
1282
1283 int sas_read_port_mode_page(struct scsi_device *sdev)
1284 {
1285         char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata;
1286         struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
1287         struct scsi_mode_data mode_data;
1288         int res, error;
1289
1290         if (!buffer)
1291                 return -ENOMEM;
1292
1293         res = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3,
1294                               &mode_data, NULL);
1295
1296         error = -EINVAL;
1297         if (!scsi_status_is_good(res))
1298                 goto out;
1299
1300         msdata = buffer +  mode_data.header_length +
1301                 mode_data.block_descriptor_length;
1302
1303         if (msdata - buffer > BUF_SIZE - 8)
1304                 goto out;
1305
1306         error = 0;
1307
1308         rdev->ready_led_meaning = msdata[2] & 0x10 ? 1 : 0;
1309         rdev->I_T_nexus_loss_timeout = (msdata[4] << 8) + msdata[5];
1310         rdev->initiator_response_timeout = (msdata[6] << 8) + msdata[7];
1311
1312  out:
1313         kfree(buffer);
1314         return error;
1315 }
1316 EXPORT_SYMBOL(sas_read_port_mode_page);
1317
1318 static DECLARE_TRANSPORT_CLASS(sas_end_dev_class,
1319                                "sas_end_device", NULL, NULL, NULL);
1320
1321 #define sas_end_dev_show_simple(field, name, format_string, cast)       \
1322 static ssize_t                                                          \
1323 show_sas_end_dev_##name(struct device *dev,                             \
1324                         struct device_attribute *attr, char *buf)       \
1325 {                                                                       \
1326         struct sas_rphy *rphy = transport_class_to_rphy(dev);           \
1327         struct sas_end_device *rdev = rphy_to_end_device(rphy);         \
1328                                                                         \
1329         return snprintf(buf, 20, format_string, cast rdev->field);      \
1330 }
1331
1332 #define sas_end_dev_simple_attr(field, name, format_string, type)       \
1333         sas_end_dev_show_simple(field, name, format_string, (type))     \
1334 static SAS_DEVICE_ATTR(end_dev, name, S_IRUGO,                  \
1335                 show_sas_end_dev_##name, NULL)
1336
1337 sas_end_dev_simple_attr(ready_led_meaning, ready_led_meaning, "%d\n", int);
1338 sas_end_dev_simple_attr(I_T_nexus_loss_timeout, I_T_nexus_loss_timeout,
1339                         "%d\n", int);
1340 sas_end_dev_simple_attr(initiator_response_timeout, initiator_response_timeout,
1341                         "%d\n", int);
1342 sas_end_dev_simple_attr(tlr_supported, tlr_supported,
1343                         "%d\n", int);
1344 sas_end_dev_simple_attr(tlr_enabled, tlr_enabled,
1345                         "%d\n", int);
1346
1347 static DECLARE_TRANSPORT_CLASS(sas_expander_class,
1348                                "sas_expander", NULL, NULL, NULL);
1349
1350 #define sas_expander_show_simple(field, name, format_string, cast)      \
1351 static ssize_t                                                          \
1352 show_sas_expander_##name(struct device *dev,                            \
1353                          struct device_attribute *attr, char *buf)      \
1354 {                                                                       \
1355         struct sas_rphy *rphy = transport_class_to_rphy(dev);           \
1356         struct sas_expander_device *edev = rphy_to_expander_device(rphy); \
1357                                                                         \
1358         return snprintf(buf, 20, format_string, cast edev->field);      \
1359 }
1360
1361 #define sas_expander_simple_attr(field, name, format_string, type)      \
1362         sas_expander_show_simple(field, name, format_string, (type))    \
1363 static SAS_DEVICE_ATTR(expander, name, S_IRUGO,                         \
1364                 show_sas_expander_##name, NULL)
1365
1366 sas_expander_simple_attr(vendor_id, vendor_id, "%s\n", char *);
1367 sas_expander_simple_attr(product_id, product_id, "%s\n", char *);
1368 sas_expander_simple_attr(product_rev, product_rev, "%s\n", char *);
1369 sas_expander_simple_attr(component_vendor_id, component_vendor_id,
1370                          "%s\n", char *);
1371 sas_expander_simple_attr(component_id, component_id, "%u\n", unsigned int);
1372 sas_expander_simple_attr(component_revision_id, component_revision_id, "%u\n",
1373                          unsigned int);
1374 sas_expander_simple_attr(level, level, "%d\n", int);
1375
1376 static DECLARE_TRANSPORT_CLASS(sas_rphy_class,
1377                 "sas_device", NULL, NULL, NULL);
1378
1379 static int sas_rphy_match(struct attribute_container *cont, struct device *dev)
1380 {
1381         struct Scsi_Host *shost;
1382         struct sas_internal *i;
1383
1384         if (!scsi_is_sas_rphy(dev))
1385                 return 0;
1386         shost = dev_to_shost(dev->parent->parent);
1387
1388         if (!shost->transportt)
1389                 return 0;
1390         if (shost->transportt->host_attrs.ac.class !=
1391                         &sas_host_class.class)
1392                 return 0;
1393
1394         i = to_sas_internal(shost->transportt);
1395         return &i->rphy_attr_cont.ac == cont;
1396 }
1397
1398 static int sas_end_dev_match(struct attribute_container *cont,
1399                              struct device *dev)
1400 {
1401         struct Scsi_Host *shost;
1402         struct sas_internal *i;
1403         struct sas_rphy *rphy;
1404
1405         if (!scsi_is_sas_rphy(dev))
1406                 return 0;
1407         shost = dev_to_shost(dev->parent->parent);
1408         rphy = dev_to_rphy(dev);
1409
1410         if (!shost->transportt)
1411                 return 0;
1412         if (shost->transportt->host_attrs.ac.class !=
1413                         &sas_host_class.class)
1414                 return 0;
1415
1416         i = to_sas_internal(shost->transportt);
1417         return &i->end_dev_attr_cont.ac == cont &&
1418                 rphy->identify.device_type == SAS_END_DEVICE;
1419 }
1420
1421 static int sas_expander_match(struct attribute_container *cont,
1422                               struct device *dev)
1423 {
1424         struct Scsi_Host *shost;
1425         struct sas_internal *i;
1426         struct sas_rphy *rphy;
1427
1428         if (!scsi_is_sas_rphy(dev))
1429                 return 0;
1430         shost = dev_to_shost(dev->parent->parent);
1431         rphy = dev_to_rphy(dev);
1432
1433         if (!shost->transportt)
1434                 return 0;
1435         if (shost->transportt->host_attrs.ac.class !=
1436                         &sas_host_class.class)
1437                 return 0;
1438
1439         i = to_sas_internal(shost->transportt);
1440         return &i->expander_attr_cont.ac == cont &&
1441                 (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
1442                  rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE);
1443 }
1444
1445 static void sas_expander_release(struct device *dev)
1446 {
1447         struct sas_rphy *rphy = dev_to_rphy(dev);
1448         struct sas_expander_device *edev = rphy_to_expander_device(rphy);
1449
1450         if (rphy->q)
1451                 blk_cleanup_queue(rphy->q);
1452
1453         put_device(dev->parent);
1454         kfree(edev);
1455 }
1456
1457 static void sas_end_device_release(struct device *dev)
1458 {
1459         struct sas_rphy *rphy = dev_to_rphy(dev);
1460         struct sas_end_device *edev = rphy_to_end_device(rphy);
1461
1462         if (rphy->q)
1463                 blk_cleanup_queue(rphy->q);
1464
1465         put_device(dev->parent);
1466         kfree(edev);
1467 }
1468
1469 /**
1470  * sas_rphy_initialize - common rphy intialization
1471  * @rphy:       rphy to initialise
1472  *
1473  * Used by both sas_end_device_alloc() and sas_expander_alloc() to
1474  * initialise the common rphy component of each.
1475  */
1476 static void sas_rphy_initialize(struct sas_rphy *rphy)
1477 {
1478         INIT_LIST_HEAD(&rphy->list);
1479 }
1480
1481 /**
1482  * sas_end_device_alloc - allocate an rphy for an end device
1483  * @parent: which port
1484  *
1485  * Allocates an SAS remote PHY structure, connected to @parent.
1486  *
1487  * Returns:
1488  *      SAS PHY allocated or %NULL if the allocation failed.
1489  */
1490 struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)
1491 {
1492         struct Scsi_Host *shost = dev_to_shost(&parent->dev);
1493         struct sas_end_device *rdev;
1494
1495         rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
1496         if (!rdev) {
1497                 return NULL;
1498         }
1499
1500         device_initialize(&rdev->rphy.dev);
1501         rdev->rphy.dev.parent = get_device(&parent->dev);
1502         rdev->rphy.dev.release = sas_end_device_release;
1503         if (scsi_is_sas_expander_device(parent->dev.parent)) {
1504                 struct sas_rphy *rphy = dev_to_rphy(parent->dev.parent);
1505                 dev_set_name(&rdev->rphy.dev, "end_device-%d:%d:%d",
1506                              shost->host_no, rphy->scsi_target_id,
1507                              parent->port_identifier);
1508         } else
1509                 dev_set_name(&rdev->rphy.dev, "end_device-%d:%d",
1510                              shost->host_no, parent->port_identifier);
1511         rdev->rphy.identify.device_type = SAS_END_DEVICE;
1512         sas_rphy_initialize(&rdev->rphy);
1513         transport_setup_device(&rdev->rphy.dev);
1514
1515         return &rdev->rphy;
1516 }
1517 EXPORT_SYMBOL(sas_end_device_alloc);
1518
1519 /**
1520  * sas_expander_alloc - allocate an rphy for an end device
1521  * @parent: which port
1522  * @type: SAS_EDGE_EXPANDER_DEVICE or SAS_FANOUT_EXPANDER_DEVICE
1523  *
1524  * Allocates an SAS remote PHY structure, connected to @parent.
1525  *
1526  * Returns:
1527  *      SAS PHY allocated or %NULL if the allocation failed.
1528  */
1529 struct sas_rphy *sas_expander_alloc(struct sas_port *parent,
1530                                     enum sas_device_type type)
1531 {
1532         struct Scsi_Host *shost = dev_to_shost(&parent->dev);
1533         struct sas_expander_device *rdev;
1534         struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
1535
1536         BUG_ON(type != SAS_EDGE_EXPANDER_DEVICE &&
1537                type != SAS_FANOUT_EXPANDER_DEVICE);
1538
1539         rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
1540         if (!rdev) {
1541                 return NULL;
1542         }
1543
1544         device_initialize(&rdev->rphy.dev);
1545         rdev->rphy.dev.parent = get_device(&parent->dev);
1546         rdev->rphy.dev.release = sas_expander_release;
1547         mutex_lock(&sas_host->lock);
1548         rdev->rphy.scsi_target_id = sas_host->next_expander_id++;
1549         mutex_unlock(&sas_host->lock);
1550         dev_set_name(&rdev->rphy.dev, "expander-%d:%d",
1551                      shost->host_no, rdev->rphy.scsi_target_id);
1552         rdev->rphy.identify.device_type = type;
1553         sas_rphy_initialize(&rdev->rphy);
1554         transport_setup_device(&rdev->rphy.dev);
1555
1556         return &rdev->rphy;
1557 }
1558 EXPORT_SYMBOL(sas_expander_alloc);
1559
1560 /**
1561  * sas_rphy_add  -  add a SAS remote PHY to the device hierarchy
1562  * @rphy:       The remote PHY to be added
1563  *
1564  * Publishes a SAS remote PHY to the rest of the system.
1565  */
1566 int sas_rphy_add(struct sas_rphy *rphy)
1567 {
1568         struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
1569         struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
1570         struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
1571         struct sas_identify *identify = &rphy->identify;
1572         int error;
1573
1574         if (parent->rphy)
1575                 return -ENXIO;
1576         parent->rphy = rphy;
1577
1578         error = device_add(&rphy->dev);
1579         if (error)
1580                 return error;
1581         transport_add_device(&rphy->dev);
1582         transport_configure_device(&rphy->dev);
1583         if (sas_bsg_initialize(shost, rphy))
1584                 printk("fail to a bsg device %s\n", dev_name(&rphy->dev));
1585
1586
1587         mutex_lock(&sas_host->lock);
1588         list_add_tail(&rphy->list, &sas_host->rphy_list);
1589         if (identify->device_type == SAS_END_DEVICE &&
1590             (identify->target_port_protocols &
1591              (SAS_PROTOCOL_SSP|SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA)))
1592                 rphy->scsi_target_id = sas_host->next_target_id++;
1593         else if (identify->device_type == SAS_END_DEVICE)
1594                 rphy->scsi_target_id = -1;
1595         mutex_unlock(&sas_host->lock);
1596
1597         if (identify->device_type == SAS_END_DEVICE &&
1598             rphy->scsi_target_id != -1) {
1599                 int lun;
1600
1601                 if (identify->target_port_protocols & SAS_PROTOCOL_SSP)
1602                         lun = SCAN_WILD_CARD;
1603                 else
1604                         lun = 0;
1605
1606                 scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, lun,
1607                                  SCSI_SCAN_INITIAL);
1608         }
1609
1610         return 0;
1611 }
1612 EXPORT_SYMBOL(sas_rphy_add);
1613
1614 /**
1615  * sas_rphy_free  -  free a SAS remote PHY
1616  * @rphy: SAS remote PHY to free
1617  *
1618  * Frees the specified SAS remote PHY.
1619  *
1620  * Note:
1621  *   This function must only be called on a remote
1622  *   PHY that has not successfully been added using
1623  *   sas_rphy_add() (or has been sas_rphy_remove()'d)
1624  */
1625 void sas_rphy_free(struct sas_rphy *rphy)
1626 {
1627         struct device *dev = &rphy->dev;
1628         struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
1629         struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
1630
1631         mutex_lock(&sas_host->lock);
1632         list_del(&rphy->list);
1633         mutex_unlock(&sas_host->lock);
1634
1635         transport_destroy_device(dev);
1636
1637         put_device(dev);
1638 }
1639 EXPORT_SYMBOL(sas_rphy_free);
1640
1641 /**
1642  * sas_rphy_delete  -  remove and free SAS remote PHY
1643  * @rphy:       SAS remote PHY to remove and free
1644  *
1645  * Removes the specified SAS remote PHY and frees it.
1646  */
1647 void
1648 sas_rphy_delete(struct sas_rphy *rphy)
1649 {
1650         sas_rphy_remove(rphy);
1651         sas_rphy_free(rphy);
1652 }
1653 EXPORT_SYMBOL(sas_rphy_delete);
1654
1655 /**
1656  * sas_rphy_unlink  -  unlink SAS remote PHY
1657  * @rphy:       SAS remote phy to unlink from its parent port
1658  *
1659  * Removes port reference to an rphy
1660  */
1661 void sas_rphy_unlink(struct sas_rphy *rphy)
1662 {
1663         struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
1664
1665         parent->rphy = NULL;
1666 }
1667 EXPORT_SYMBOL(sas_rphy_unlink);
1668
1669 /**
1670  * sas_rphy_remove  -  remove SAS remote PHY
1671  * @rphy:       SAS remote phy to remove
1672  *
1673  * Removes the specified SAS remote PHY.
1674  */
1675 void
1676 sas_rphy_remove(struct sas_rphy *rphy)
1677 {
1678         struct device *dev = &rphy->dev;
1679
1680         switch (rphy->identify.device_type) {
1681         case SAS_END_DEVICE:
1682                 scsi_remove_target(dev);
1683                 break;
1684         case SAS_EDGE_EXPANDER_DEVICE:
1685         case SAS_FANOUT_EXPANDER_DEVICE:
1686                 sas_remove_children(dev);
1687                 break;
1688         default:
1689                 break;
1690         }
1691
1692         sas_rphy_unlink(rphy);
1693         sas_bsg_remove(NULL, rphy);
1694         transport_remove_device(dev);
1695         device_del(dev);
1696 }
1697 EXPORT_SYMBOL(sas_rphy_remove);
1698
1699 /**
1700  * scsi_is_sas_rphy  -  check if a struct device represents a SAS remote PHY
1701  * @dev:        device to check
1702  *
1703  * Returns:
1704  *      %1 if the device represents a SAS remote PHY, %0 else
1705  */
1706 int scsi_is_sas_rphy(const struct device *dev)
1707 {
1708         return dev->release == sas_end_device_release ||
1709                 dev->release == sas_expander_release;
1710 }
1711 EXPORT_SYMBOL(scsi_is_sas_rphy);
1712
1713
1714 /*
1715  * SCSI scan helper
1716  */
1717
1718 static int sas_user_scan(struct Scsi_Host *shost, uint channel,
1719                 uint id, u64 lun)
1720 {
1721         struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
1722         struct sas_rphy *rphy;
1723
1724         mutex_lock(&sas_host->lock);
1725         list_for_each_entry(rphy, &sas_host->rphy_list, list) {
1726                 if (rphy->identify.device_type != SAS_END_DEVICE ||
1727                     rphy->scsi_target_id == -1)
1728                         continue;
1729
1730                 if ((channel == SCAN_WILD_CARD || channel == 0) &&
1731                     (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
1732                         scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id,
1733                                          lun, SCSI_SCAN_MANUAL);
1734                 }
1735         }
1736         mutex_unlock(&sas_host->lock);
1737
1738         return 0;
1739 }
1740
1741
1742 /*
1743  * Setup / Teardown code
1744  */
1745
1746 #define SETUP_TEMPLATE(attrb, field, perm, test)                        \
1747         i->private_##attrb[count] = dev_attr_##field;           \
1748         i->private_##attrb[count].attr.mode = perm;                     \
1749         i->attrb[count] = &i->private_##attrb[count];                   \
1750         if (test)                                                       \
1751                 count++
1752
1753 #define SETUP_TEMPLATE_RW(attrb, field, perm, test, ro_test, ro_perm)   \
1754         i->private_##attrb[count] = dev_attr_##field;           \
1755         i->private_##attrb[count].attr.mode = perm;                     \
1756         if (ro_test) {                                                  \
1757                 i->private_##attrb[count].attr.mode = ro_perm;          \
1758                 i->private_##attrb[count].store = NULL;                 \
1759         }                                                               \
1760         i->attrb[count] = &i->private_##attrb[count];                   \
1761         if (test)                                                       \
1762                 count++
1763
1764 #define SETUP_RPORT_ATTRIBUTE(field)                                    \
1765         SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, 1)
1766
1767 #define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func)                     \
1768         SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func)
1769
1770 #define SETUP_PHY_ATTRIBUTE(field)                                      \
1771         SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1)
1772
1773 #define SETUP_PHY_ATTRIBUTE_RW(field)                                   \
1774         SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1,       \
1775                         !i->f->set_phy_speed, S_IRUGO)
1776
1777 #define SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(field, func)                    \
1778         SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1,       \
1779                           !i->f->func, S_IRUGO)
1780
1781 #define SETUP_PORT_ATTRIBUTE(field)                                     \
1782         SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
1783
1784 #define SETUP_OPTIONAL_PHY_ATTRIBUTE(field, func)                       \
1785         SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func)
1786
1787 #define SETUP_PHY_ATTRIBUTE_WRONLY(field)                               \
1788         SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, 1)
1789
1790 #define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func)                \
1791         SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, i->f->func)
1792
1793 #define SETUP_END_DEV_ATTRIBUTE(field)                                  \
1794         SETUP_TEMPLATE(end_dev_attrs, field, S_IRUGO, 1)
1795
1796 #define SETUP_EXPANDER_ATTRIBUTE(field)                                 \
1797         SETUP_TEMPLATE(expander_attrs, expander_##field, S_IRUGO, 1)
1798
1799 /**
1800  * sas_attach_transport  -  instantiate SAS transport template
1801  * @ft:         SAS transport class function template
1802  */
1803 struct scsi_transport_template *
1804 sas_attach_transport(struct sas_function_template *ft)
1805 {
1806         struct sas_internal *i;
1807         int count;
1808
1809         i = kzalloc(sizeof(struct sas_internal), GFP_KERNEL);
1810         if (!i)
1811                 return NULL;
1812
1813         i->t.user_scan = sas_user_scan;
1814
1815         i->t.host_attrs.ac.attrs = &i->host_attrs[0];
1816         i->t.host_attrs.ac.class = &sas_host_class.class;
1817         i->t.host_attrs.ac.match = sas_host_match;
1818         transport_container_register(&i->t.host_attrs);
1819         i->t.host_size = sizeof(struct sas_host_attrs);
1820
1821         i->phy_attr_cont.ac.class = &sas_phy_class.class;
1822         i->phy_attr_cont.ac.attrs = &i->phy_attrs[0];
1823         i->phy_attr_cont.ac.match = sas_phy_match;
1824         transport_container_register(&i->phy_attr_cont);
1825
1826         i->port_attr_cont.ac.class = &sas_port_class.class;
1827         i->port_attr_cont.ac.attrs = &i->port_attrs[0];
1828         i->port_attr_cont.ac.match = sas_port_match;
1829         transport_container_register(&i->port_attr_cont);
1830
1831         i->rphy_attr_cont.ac.class = &sas_rphy_class.class;
1832         i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0];
1833         i->rphy_attr_cont.ac.match = sas_rphy_match;
1834         transport_container_register(&i->rphy_attr_cont);
1835
1836         i->end_dev_attr_cont.ac.class = &sas_end_dev_class.class;
1837         i->end_dev_attr_cont.ac.attrs = &i->end_dev_attrs[0];
1838         i->end_dev_attr_cont.ac.match = sas_end_dev_match;
1839         transport_container_register(&i->end_dev_attr_cont);
1840
1841         i->expander_attr_cont.ac.class = &sas_expander_class.class;
1842         i->expander_attr_cont.ac.attrs = &i->expander_attrs[0];
1843         i->expander_attr_cont.ac.match = sas_expander_match;
1844         transport_container_register(&i->expander_attr_cont);
1845
1846         i->f = ft;
1847
1848         count = 0;
1849         SETUP_PHY_ATTRIBUTE(initiator_port_protocols);
1850         SETUP_PHY_ATTRIBUTE(target_port_protocols);
1851         SETUP_PHY_ATTRIBUTE(device_type);
1852         SETUP_PHY_ATTRIBUTE(sas_address);
1853         SETUP_PHY_ATTRIBUTE(phy_identifier);
1854         //SETUP_PHY_ATTRIBUTE(port_identifier);
1855         SETUP_PHY_ATTRIBUTE(negotiated_linkrate);
1856         SETUP_PHY_ATTRIBUTE(minimum_linkrate_hw);
1857         SETUP_PHY_ATTRIBUTE_RW(minimum_linkrate);
1858         SETUP_PHY_ATTRIBUTE(maximum_linkrate_hw);
1859         SETUP_PHY_ATTRIBUTE_RW(maximum_linkrate);
1860
1861         SETUP_PHY_ATTRIBUTE(invalid_dword_count);
1862         SETUP_PHY_ATTRIBUTE(running_disparity_error_count);
1863         SETUP_PHY_ATTRIBUTE(loss_of_dword_sync_count);
1864         SETUP_PHY_ATTRIBUTE(phy_reset_problem_count);
1865         SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset);
1866         SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset);
1867         SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(enable, phy_enable);
1868         i->phy_attrs[count] = NULL;
1869
1870         count = 0;
1871         SETUP_PORT_ATTRIBUTE(num_phys);
1872         i->port_attrs[count] = NULL;
1873
1874         count = 0;
1875         SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols);
1876         SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols);
1877         SETUP_RPORT_ATTRIBUTE(rphy_device_type);
1878         SETUP_RPORT_ATTRIBUTE(rphy_sas_address);
1879         SETUP_RPORT_ATTRIBUTE(rphy_phy_identifier);
1880         SETUP_RPORT_ATTRIBUTE(rphy_scsi_target_id);
1881         SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_enclosure_identifier,
1882                                        get_enclosure_identifier);
1883         SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_bay_identifier,
1884                                        get_bay_identifier);
1885         i->rphy_attrs[count] = NULL;
1886
1887         count = 0;
1888         SETUP_END_DEV_ATTRIBUTE(end_dev_ready_led_meaning);
1889         SETUP_END_DEV_ATTRIBUTE(end_dev_I_T_nexus_loss_timeout);
1890         SETUP_END_DEV_ATTRIBUTE(end_dev_initiator_response_timeout);
1891         SETUP_END_DEV_ATTRIBUTE(end_dev_tlr_supported);
1892         SETUP_END_DEV_ATTRIBUTE(end_dev_tlr_enabled);
1893         i->end_dev_attrs[count] = NULL;
1894
1895         count = 0;
1896         SETUP_EXPANDER_ATTRIBUTE(vendor_id);
1897         SETUP_EXPANDER_ATTRIBUTE(product_id);
1898         SETUP_EXPANDER_ATTRIBUTE(product_rev);
1899         SETUP_EXPANDER_ATTRIBUTE(component_vendor_id);
1900         SETUP_EXPANDER_ATTRIBUTE(component_id);
1901         SETUP_EXPANDER_ATTRIBUTE(component_revision_id);
1902         SETUP_EXPANDER_ATTRIBUTE(level);
1903         i->expander_attrs[count] = NULL;
1904
1905         return &i->t;
1906 }
1907 EXPORT_SYMBOL(sas_attach_transport);
1908
1909 /**
1910  * sas_release_transport  -  release SAS transport template instance
1911  * @t:          transport template instance
1912  */
1913 void sas_release_transport(struct scsi_transport_template *t)
1914 {
1915         struct sas_internal *i = to_sas_internal(t);
1916
1917         transport_container_unregister(&i->t.host_attrs);
1918         transport_container_unregister(&i->phy_attr_cont);
1919         transport_container_unregister(&i->port_attr_cont);
1920         transport_container_unregister(&i->rphy_attr_cont);
1921         transport_container_unregister(&i->end_dev_attr_cont);
1922         transport_container_unregister(&i->expander_attr_cont);
1923
1924         kfree(i);
1925 }
1926 EXPORT_SYMBOL(sas_release_transport);
1927
1928 static __init int sas_transport_init(void)
1929 {
1930         int error;
1931
1932         error = transport_class_register(&sas_host_class);
1933         if (error)
1934                 goto out;
1935         error = transport_class_register(&sas_phy_class);
1936         if (error)
1937                 goto out_unregister_transport;
1938         error = transport_class_register(&sas_port_class);
1939         if (error)
1940                 goto out_unregister_phy;
1941         error = transport_class_register(&sas_rphy_class);
1942         if (error)
1943                 goto out_unregister_port;
1944         error = transport_class_register(&sas_end_dev_class);
1945         if (error)
1946                 goto out_unregister_rphy;
1947         error = transport_class_register(&sas_expander_class);
1948         if (error)
1949                 goto out_unregister_end_dev;
1950
1951         return 0;
1952
1953  out_unregister_end_dev:
1954         transport_class_unregister(&sas_end_dev_class);
1955  out_unregister_rphy:
1956         transport_class_unregister(&sas_rphy_class);
1957  out_unregister_port:
1958         transport_class_unregister(&sas_port_class);
1959  out_unregister_phy:
1960         transport_class_unregister(&sas_phy_class);
1961  out_unregister_transport:
1962         transport_class_unregister(&sas_host_class);
1963  out:
1964         return error;
1965
1966 }
1967
1968 static void __exit sas_transport_exit(void)
1969 {
1970         transport_class_unregister(&sas_host_class);
1971         transport_class_unregister(&sas_phy_class);
1972         transport_class_unregister(&sas_port_class);
1973         transport_class_unregister(&sas_rphy_class);
1974         transport_class_unregister(&sas_end_dev_class);
1975         transport_class_unregister(&sas_expander_class);
1976 }
1977
1978 MODULE_AUTHOR("Christoph Hellwig");
1979 MODULE_DESCRIPTION("SAS Transport Attributes");
1980 MODULE_LICENSE("GPL");
1981
1982 module_init(sas_transport_init);
1983 module_exit(sas_transport_exit);
This page took 0.152464 seconds and 4 git commands to generate.