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