diff options
Diffstat (limited to 'drivers/scsi/scsi_transport_sas.c')
| -rw-r--r-- | drivers/scsi/scsi_transport_sas.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 5c0b75bbfa10..9e38c1894bb2 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
| @@ -336,6 +336,51 @@ show_sas_device_type(struct class_device *cdev, char *buf) | |||
| 336 | } | 336 | } |
| 337 | static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL); | 337 | static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL); |
| 338 | 338 | ||
| 339 | static ssize_t do_sas_phy_enable(struct class_device *cdev, | ||
| 340 | size_t count, int enable) | ||
| 341 | { | ||
| 342 | struct sas_phy *phy = transport_class_to_phy(cdev); | ||
| 343 | struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); | ||
| 344 | struct sas_internal *i = to_sas_internal(shost->transportt); | ||
| 345 | int error; | ||
| 346 | |||
| 347 | error = i->f->phy_enable(phy, enable); | ||
| 348 | if (error) | ||
| 349 | return error; | ||
| 350 | phy->enabled = enable; | ||
| 351 | return count; | ||
| 352 | }; | ||
| 353 | |||
| 354 | static ssize_t store_sas_phy_enable(struct class_device *cdev, | ||
| 355 | const char *buf, size_t count) | ||
| 356 | { | ||
| 357 | if (count < 1) | ||
| 358 | return -EINVAL; | ||
| 359 | |||
| 360 | switch (buf[0]) { | ||
| 361 | case '0': | ||
| 362 | do_sas_phy_enable(cdev, count, 0); | ||
| 363 | break; | ||
| 364 | case '1': | ||
| 365 | do_sas_phy_enable(cdev, count, 1); | ||
| 366 | break; | ||
| 367 | default: | ||
| 368 | return -EINVAL; | ||
| 369 | } | ||
| 370 | |||
| 371 | return count; | ||
| 372 | } | ||
| 373 | |||
| 374 | static ssize_t show_sas_phy_enable(struct class_device *cdev, char *buf) | ||
| 375 | { | ||
| 376 | struct sas_phy *phy = transport_class_to_phy(cdev); | ||
| 377 | |||
| 378 | return snprintf(buf, 20, "%d", phy->enabled); | ||
| 379 | } | ||
| 380 | |||
| 381 | static CLASS_DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, show_sas_phy_enable, | ||
| 382 | store_sas_phy_enable); | ||
| 383 | |||
| 339 | static ssize_t do_sas_phy_reset(struct class_device *cdev, | 384 | static ssize_t do_sas_phy_reset(struct class_device *cdev, |
| 340 | size_t count, int hard_reset) | 385 | size_t count, int hard_reset) |
| 341 | { | 386 | { |
| @@ -435,6 +480,7 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number) | |||
| 435 | return NULL; | 480 | return NULL; |
| 436 | 481 | ||
| 437 | phy->number = number; | 482 | phy->number = number; |
| 483 | phy->enabled = 1; | ||
| 438 | 484 | ||
| 439 | device_initialize(&phy->dev); | 485 | device_initialize(&phy->dev); |
| 440 | phy->dev.parent = get_device(parent); | 486 | phy->dev.parent = get_device(parent); |
| @@ -1389,6 +1435,10 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
| 1389 | SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1, \ | 1435 | SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1, \ |
| 1390 | !i->f->set_phy_speed, S_IRUGO) | 1436 | !i->f->set_phy_speed, S_IRUGO) |
| 1391 | 1437 | ||
| 1438 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(field, func) \ | ||
| 1439 | SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1, \ | ||
| 1440 | !i->f->func, S_IRUGO) | ||
| 1441 | |||
| 1392 | #define SETUP_PORT_ATTRIBUTE(field) \ | 1442 | #define SETUP_PORT_ATTRIBUTE(field) \ |
| 1393 | SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1) | 1443 | SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1) |
| 1394 | 1444 | ||
| @@ -1479,6 +1529,7 @@ sas_attach_transport(struct sas_function_template *ft) | |||
| 1479 | SETUP_PHY_ATTRIBUTE(phy_reset_problem_count); | 1529 | SETUP_PHY_ATTRIBUTE(phy_reset_problem_count); |
| 1480 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset); | 1530 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset); |
| 1481 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset); | 1531 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset); |
| 1532 | SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(enable, phy_enable); | ||
| 1482 | i->phy_attrs[count] = NULL; | 1533 | i->phy_attrs[count] = NULL; |
| 1483 | 1534 | ||
| 1484 | count = 0; | 1535 | count = 0; |
