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