ses.c revision 7c46c20aef185c3782d28c5111dcf1df88bbab32
1/* 2 * SCSI Enclosure Services 3 * 4 * Copyright (C) 2008 James Bottomley <James.Bottomley@HansenPartnership.com> 5 * 6**----------------------------------------------------------------------------- 7** 8** This program is free software; you can redistribute it and/or 9** modify it under the terms of the GNU General Public License 10** version 2 as published by the Free Software Foundation. 11** 12** This program is distributed in the hope that it will be useful, 13** but WITHOUT ANY WARRANTY; without even the implied warranty of 14** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15** GNU General Public License for more details. 16** 17** You should have received a copy of the GNU General Public License 18** along with this program; if not, write to the Free Software 19** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20** 21**----------------------------------------------------------------------------- 22*/ 23 24#include <linux/module.h> 25#include <linux/kernel.h> 26#include <linux/enclosure.h> 27 28#include <scsi/scsi.h> 29#include <scsi/scsi_cmnd.h> 30#include <scsi/scsi_dbg.h> 31#include <scsi/scsi_device.h> 32#include <scsi/scsi_driver.h> 33#include <scsi/scsi_host.h> 34 35struct ses_device { 36 char *page1; 37 char *page2; 38 char *page10; 39 short page1_len; 40 short page2_len; 41 short page10_len; 42}; 43 44struct ses_component { 45 u64 addr; 46 unsigned char *desc; 47}; 48 49static int ses_probe(struct device *dev) 50{ 51 struct scsi_device *sdev = to_scsi_device(dev); 52 int err = -ENODEV; 53 54 if (sdev->type != TYPE_ENCLOSURE) 55 goto out; 56 57 err = 0; 58 sdev_printk(KERN_NOTICE, sdev, "Attached Enclosure device\n"); 59 60 out: 61 return err; 62} 63 64#define SES_TIMEOUT 30 65#define SES_RETRIES 3 66 67static int ses_recv_diag(struct scsi_device *sdev, int page_code, 68 void *buf, int bufflen) 69{ 70 char cmd[] = { 71 RECEIVE_DIAGNOSTIC, 72 1, /* Set PCV bit */ 73 page_code, 74 bufflen >> 8, 75 bufflen & 0xff, 76 0 77 }; 78 79 return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, 80 NULL, SES_TIMEOUT, SES_RETRIES); 81} 82 83static int ses_send_diag(struct scsi_device *sdev, int page_code, 84 void *buf, int bufflen) 85{ 86 u32 result; 87 88 char cmd[] = { 89 SEND_DIAGNOSTIC, 90 0x10, /* Set PF bit */ 91 0, 92 bufflen >> 8, 93 bufflen & 0xff, 94 0 95 }; 96 97 result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen, 98 NULL, SES_TIMEOUT, SES_RETRIES); 99 if (result) 100 sdev_printk(KERN_ERR, sdev, "SEND DIAGNOSTIC result: %8x\n", 101 result); 102 return result; 103} 104 105static int ses_set_page2_descriptor(struct enclosure_device *edev, 106 struct enclosure_component *ecomp, 107 char *desc) 108{ 109 int i, j, count = 0, descriptor = ecomp->number; 110 struct scsi_device *sdev = to_scsi_device(edev->cdev.dev); 111 struct ses_device *ses_dev = edev->scratch; 112 char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; 113 char *desc_ptr = ses_dev->page2 + 8; 114 115 /* Clear everything */ 116 memset(desc_ptr, 0, ses_dev->page2_len - 8); 117 for (i = 0; i < ses_dev->page1[10]; i++, type_ptr += 4) { 118 for (j = 0; j < type_ptr[1]; j++) { 119 desc_ptr += 4; 120 if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE && 121 type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE) 122 continue; 123 if (count++ == descriptor) { 124 memcpy(desc_ptr, desc, 4); 125 /* set select */ 126 desc_ptr[0] |= 0x80; 127 /* clear reserved, just in case */ 128 desc_ptr[0] &= 0xf0; 129 } 130 } 131 } 132 133 return ses_send_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len); 134} 135 136static char *ses_get_page2_descriptor(struct enclosure_device *edev, 137 struct enclosure_component *ecomp) 138{ 139 int i, j, count = 0, descriptor = ecomp->number; 140 struct scsi_device *sdev = to_scsi_device(edev->cdev.dev); 141 struct ses_device *ses_dev = edev->scratch; 142 char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; 143 char *desc_ptr = ses_dev->page2 + 8; 144 145 ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len); 146 147 for (i = 0; i < ses_dev->page1[10]; i++, type_ptr += 4) { 148 for (j = 0; j < type_ptr[1]; j++) { 149 desc_ptr += 4; 150 if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE && 151 type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE) 152 continue; 153 if (count++ == descriptor) 154 return desc_ptr; 155 } 156 } 157 return NULL; 158} 159 160static void ses_get_fault(struct enclosure_device *edev, 161 struct enclosure_component *ecomp) 162{ 163 char *desc; 164 165 desc = ses_get_page2_descriptor(edev, ecomp); 166 ecomp->fault = (desc[3] & 0x60) >> 4; 167} 168 169static int ses_set_fault(struct enclosure_device *edev, 170 struct enclosure_component *ecomp, 171 enum enclosure_component_setting val) 172{ 173 char desc[4] = {0 }; 174 175 switch (val) { 176 case ENCLOSURE_SETTING_DISABLED: 177 /* zero is disabled */ 178 break; 179 case ENCLOSURE_SETTING_ENABLED: 180 desc[2] = 0x02; 181 break; 182 default: 183 /* SES doesn't do the SGPIO blink settings */ 184 return -EINVAL; 185 } 186 187 return ses_set_page2_descriptor(edev, ecomp, desc); 188} 189 190static void ses_get_status(struct enclosure_device *edev, 191 struct enclosure_component *ecomp) 192{ 193 char *desc; 194 195 desc = ses_get_page2_descriptor(edev, ecomp); 196 ecomp->status = (desc[0] & 0x0f); 197} 198 199static void ses_get_locate(struct enclosure_device *edev, 200 struct enclosure_component *ecomp) 201{ 202 char *desc; 203 204 desc = ses_get_page2_descriptor(edev, ecomp); 205 ecomp->locate = (desc[2] & 0x02) ? 1 : 0; 206} 207 208static int ses_set_locate(struct enclosure_device *edev, 209 struct enclosure_component *ecomp, 210 enum enclosure_component_setting val) 211{ 212 char desc[4] = {0 }; 213 214 switch (val) { 215 case ENCLOSURE_SETTING_DISABLED: 216 /* zero is disabled */ 217 break; 218 case ENCLOSURE_SETTING_ENABLED: 219 desc[2] = 0x02; 220 break; 221 default: 222 /* SES doesn't do the SGPIO blink settings */ 223 return -EINVAL; 224 } 225 return ses_set_page2_descriptor(edev, ecomp, desc); 226} 227 228static int ses_set_active(struct enclosure_device *edev, 229 struct enclosure_component *ecomp, 230 enum enclosure_component_setting val) 231{ 232 char desc[4] = {0 }; 233 234 switch (val) { 235 case ENCLOSURE_SETTING_DISABLED: 236 /* zero is disabled */ 237 ecomp->active = 0; 238 break; 239 case ENCLOSURE_SETTING_ENABLED: 240 desc[2] = 0x80; 241 ecomp->active = 1; 242 break; 243 default: 244 /* SES doesn't do the SGPIO blink settings */ 245 return -EINVAL; 246 } 247 return ses_set_page2_descriptor(edev, ecomp, desc); 248} 249 250static struct enclosure_component_callbacks ses_enclosure_callbacks = { 251 .get_fault = ses_get_fault, 252 .set_fault = ses_set_fault, 253 .get_status = ses_get_status, 254 .get_locate = ses_get_locate, 255 .set_locate = ses_set_locate, 256 .set_active = ses_set_active, 257}; 258 259struct ses_host_edev { 260 struct Scsi_Host *shost; 261 struct enclosure_device *edev; 262}; 263 264int ses_match_host(struct enclosure_device *edev, void *data) 265{ 266 struct ses_host_edev *sed = data; 267 struct scsi_device *sdev; 268 269 if (!scsi_is_sdev_device(edev->cdev.dev)) 270 return 0; 271 272 sdev = to_scsi_device(edev->cdev.dev); 273 274 if (sdev->host != sed->shost) 275 return 0; 276 277 sed->edev = edev; 278 return 1; 279} 280 281static void ses_process_descriptor(struct enclosure_component *ecomp, 282 unsigned char *desc) 283{ 284 int eip = desc[0] & 0x10; 285 int invalid = desc[0] & 0x80; 286 enum scsi_protocol proto = desc[0] & 0x0f; 287 u64 addr = 0; 288 struct ses_component *scomp = ecomp->scratch; 289 unsigned char *d; 290 291 scomp->desc = desc; 292 293 if (invalid) 294 return; 295 296 switch (proto) { 297 case SCSI_PROTOCOL_SAS: 298 if (eip) 299 d = desc + 8; 300 else 301 d = desc + 4; 302 /* only take the phy0 addr */ 303 addr = (u64)d[12] << 56 | 304 (u64)d[13] << 48 | 305 (u64)d[14] << 40 | 306 (u64)d[15] << 32 | 307 (u64)d[16] << 24 | 308 (u64)d[17] << 16 | 309 (u64)d[18] << 8 | 310 (u64)d[19]; 311 break; 312 default: 313 /* FIXME: Need to add more protocols than just SAS */ 314 break; 315 } 316 scomp->addr = addr; 317} 318 319struct efd { 320 u64 addr; 321 struct device *dev; 322}; 323 324static int ses_enclosure_find_by_addr(struct enclosure_device *edev, 325 void *data) 326{ 327 struct efd *efd = data; 328 int i; 329 struct ses_component *scomp; 330 331 if (!edev->component[0].scratch) 332 return 0; 333 334 for (i = 0; i < edev->components; i++) { 335 scomp = edev->component[i].scratch; 336 if (scomp->addr != efd->addr) 337 continue; 338 339 enclosure_add_device(edev, i, efd->dev); 340 return 1; 341 } 342 return 0; 343} 344 345#define VPD_INQUIRY_SIZE 512 346 347static void ses_match_to_enclosure(struct enclosure_device *edev, 348 struct scsi_device *sdev) 349{ 350 unsigned char *buf = kmalloc(VPD_INQUIRY_SIZE, GFP_KERNEL); 351 unsigned char *desc; 352 int len; 353 struct efd efd = { 354 .addr = 0, 355 }; 356 unsigned char cmd[] = { 357 INQUIRY, 358 1, 359 0x83, 360 VPD_INQUIRY_SIZE >> 8, 361 VPD_INQUIRY_SIZE & 0xff, 362 0 363 }; 364 365 if (!buf) 366 return; 367 368 if (scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, 369 VPD_INQUIRY_SIZE, NULL, SES_TIMEOUT, SES_RETRIES)) 370 goto free; 371 372 len = (buf[2] << 8) + buf[3]; 373 desc = buf + 4; 374 while (desc < buf + len) { 375 enum scsi_protocol proto = desc[0] >> 4; 376 u8 code_set = desc[0] & 0x0f; 377 u8 piv = desc[1] & 0x80; 378 u8 assoc = (desc[1] & 0x30) >> 4; 379 u8 type = desc[1] & 0x0f; 380 u8 len = desc[3]; 381 382 if (piv && code_set == 1 && assoc == 1 && code_set == 1 383 && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8) 384 efd.addr = (u64)desc[4] << 56 | 385 (u64)desc[5] << 48 | 386 (u64)desc[6] << 40 | 387 (u64)desc[7] << 32 | 388 (u64)desc[8] << 24 | 389 (u64)desc[9] << 16 | 390 (u64)desc[10] << 8 | 391 (u64)desc[11]; 392 393 desc += len + 4; 394 } 395 if (!efd.addr) 396 goto free; 397 398 efd.dev = &sdev->sdev_gendev; 399 400 enclosure_for_each_device(ses_enclosure_find_by_addr, &efd); 401 free: 402 kfree(buf); 403} 404 405#define INIT_ALLOC_SIZE 32 406 407static int ses_intf_add(struct class_device *cdev, 408 struct class_interface *intf) 409{ 410 struct scsi_device *sdev = to_scsi_device(cdev->dev); 411 struct scsi_device *tmp_sdev; 412 unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr, 413 *addl_desc_ptr; 414 struct ses_device *ses_dev; 415 u32 result; 416 int i, j, types, len, components = 0; 417 int err = -ENOMEM; 418 struct enclosure_device *edev; 419 struct ses_component *scomp = NULL; 420 421 if (!scsi_device_enclosure(sdev)) { 422 /* not an enclosure, but might be in one */ 423 edev = enclosure_find(&sdev->host->shost_gendev); 424 if (edev) { 425 ses_match_to_enclosure(edev, sdev); 426 class_device_put(&edev->cdev); 427 } 428 return -ENODEV; 429 } 430 431 /* TYPE_ENCLOSURE prints a message in probe */ 432 if (sdev->type != TYPE_ENCLOSURE) 433 sdev_printk(KERN_NOTICE, sdev, "Embedded Enclosure Device\n"); 434 435 ses_dev = kzalloc(sizeof(*ses_dev), GFP_KERNEL); 436 hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL); 437 if (!hdr_buf || !ses_dev) 438 goto err_init_free; 439 440 result = ses_recv_diag(sdev, 1, hdr_buf, INIT_ALLOC_SIZE); 441 if (result) 442 goto recv_failed; 443 444 if (hdr_buf[1] != 0) { 445 /* FIXME: need subenclosure support; I've just never 446 * seen a device with subenclosures and it makes the 447 * traversal routines more complex */ 448 sdev_printk(KERN_ERR, sdev, 449 "FIXME driver has no support for subenclosures (%d)\n", 450 buf[1]); 451 goto err_free; 452 } 453 454 len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; 455 buf = kzalloc(len, GFP_KERNEL); 456 if (!buf) 457 goto err_free; 458 459 result = ses_recv_diag(sdev, 1, buf, len); 460 if (result) 461 goto recv_failed; 462 463 types = buf[10]; 464 len = buf[11]; 465 466 type_ptr = buf + 12 + len; 467 468 for (i = 0; i < types; i++, type_ptr += 4) { 469 if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE || 470 type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) 471 components += type_ptr[1]; 472 } 473 ses_dev->page1 = buf; 474 ses_dev->page1_len = len; 475 buf = NULL; 476 477 result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE); 478 if (result) 479 goto recv_failed; 480 481 len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; 482 buf = kzalloc(len, GFP_KERNEL); 483 if (!buf) 484 goto err_free; 485 486 /* make sure getting page 2 actually works */ 487 result = ses_recv_diag(sdev, 2, buf, len); 488 if (result) 489 goto recv_failed; 490 ses_dev->page2 = buf; 491 ses_dev->page2_len = len; 492 buf = NULL; 493 494 /* The additional information page --- allows us 495 * to match up the devices */ 496 result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE); 497 if (result) 498 goto no_page10; 499 500 len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; 501 buf = kzalloc(len, GFP_KERNEL); 502 if (!buf) 503 goto err_free; 504 505 result = ses_recv_diag(sdev, 10, buf, len); 506 if (result) 507 goto recv_failed; 508 ses_dev->page10 = buf; 509 ses_dev->page10_len = len; 510 buf = NULL; 511 512 no_page10: 513 scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); 514 if (!scomp) 515 goto err_free; 516 517 edev = enclosure_register(cdev->dev, sdev->sdev_gendev.bus_id, 518 components, &ses_enclosure_callbacks); 519 if (IS_ERR(edev)) { 520 err = PTR_ERR(edev); 521 goto err_free; 522 } 523 524 edev->scratch = ses_dev; 525 for (i = 0; i < components; i++) 526 edev->component[i].scratch = scomp + i; 527 528 /* Page 7 for the descriptors is optional */ 529 result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE); 530 if (result) 531 goto simple_populate; 532 533 len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; 534 /* add 1 for trailing '\0' we'll use */ 535 buf = kzalloc(len + 1, GFP_KERNEL); 536 if (!buf) 537 goto simple_populate; 538 result = ses_recv_diag(sdev, 7, buf, len); 539 if (result) { 540 simple_populate: 541 kfree(buf); 542 buf = NULL; 543 desc_ptr = NULL; 544 addl_desc_ptr = NULL; 545 } else { 546 desc_ptr = buf + 8; 547 len = (desc_ptr[2] << 8) + desc_ptr[3]; 548 /* skip past overall descriptor */ 549 desc_ptr += len + 4; 550 addl_desc_ptr = ses_dev->page10 + 8; 551 } 552 type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; 553 components = 0; 554 for (i = 0; i < types; i++, type_ptr += 4) { 555 for (j = 0; j < type_ptr[1]; j++) { 556 char *name = NULL; 557 struct enclosure_component *ecomp; 558 559 if (desc_ptr) { 560 len = (desc_ptr[2] << 8) + desc_ptr[3]; 561 desc_ptr += 4; 562 /* Add trailing zero - pushes into 563 * reserved space */ 564 desc_ptr[len] = '\0'; 565 name = desc_ptr; 566 } 567 if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE && 568 type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE) 569 continue; 570 ecomp = enclosure_component_register(edev, 571 components++, 572 type_ptr[0], 573 name); 574 if (desc_ptr) { 575 desc_ptr += len; 576 if (!IS_ERR(ecomp)) 577 ses_process_descriptor(ecomp, 578 addl_desc_ptr); 579 580 if (addl_desc_ptr) 581 addl_desc_ptr += addl_desc_ptr[1] + 2; 582 } 583 } 584 } 585 kfree(buf); 586 kfree(hdr_buf); 587 588 /* see if there are any devices matching before 589 * we found the enclosure */ 590 shost_for_each_device(tmp_sdev, sdev->host) { 591 if (tmp_sdev->lun != 0 || scsi_device_enclosure(tmp_sdev)) 592 continue; 593 ses_match_to_enclosure(edev, tmp_sdev); 594 } 595 596 return 0; 597 598 recv_failed: 599 sdev_printk(KERN_ERR, sdev, "Failed to get diagnostic page 0x%x\n", 600 result); 601 err = -ENODEV; 602 err_free: 603 kfree(buf); 604 kfree(scomp); 605 kfree(ses_dev->page10); 606 kfree(ses_dev->page2); 607 kfree(ses_dev->page1); 608 err_init_free: 609 kfree(ses_dev); 610 kfree(hdr_buf); 611 sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n", err); 612 return err; 613} 614 615static int ses_remove(struct device *dev) 616{ 617 return 0; 618} 619 620static void ses_intf_remove(struct class_device *cdev, 621 struct class_interface *intf) 622{ 623 struct scsi_device *sdev = to_scsi_device(cdev->dev); 624 struct enclosure_device *edev; 625 struct ses_device *ses_dev; 626 627 if (!scsi_device_enclosure(sdev)) 628 return; 629 630 edev = enclosure_find(cdev->dev); 631 if (!edev) 632 return; 633 634 ses_dev = edev->scratch; 635 edev->scratch = NULL; 636 637 kfree(ses_dev->page10); 638 kfree(ses_dev->page1); 639 kfree(ses_dev->page2); 640 kfree(ses_dev); 641 642 kfree(edev->component[0].scratch); 643 644 class_device_put(&edev->cdev); 645 enclosure_unregister(edev); 646} 647 648static struct class_interface ses_interface = { 649 .add = ses_intf_add, 650 .remove = ses_intf_remove, 651}; 652 653static struct scsi_driver ses_template = { 654 .owner = THIS_MODULE, 655 .gendrv = { 656 .name = "ses", 657 .probe = ses_probe, 658 .remove = ses_remove, 659 }, 660}; 661 662static int __init ses_init(void) 663{ 664 int err; 665 666 err = scsi_register_interface(&ses_interface); 667 if (err) 668 return err; 669 670 err = scsi_register_driver(&ses_template.gendrv); 671 if (err) 672 goto out_unreg; 673 674 return 0; 675 676 out_unreg: 677 scsi_unregister_interface(&ses_interface); 678 return err; 679} 680 681static void __exit ses_exit(void) 682{ 683 scsi_unregister_driver(&ses_template.gendrv); 684 scsi_unregister_interface(&ses_interface); 685} 686 687module_init(ses_init); 688module_exit(ses_exit); 689 690MODULE_ALIAS_SCSI_DEVICE(TYPE_ENCLOSURE); 691 692MODULE_AUTHOR("James Bottomley"); 693MODULE_DESCRIPTION("SCSI Enclosure Services (ses) driver"); 694MODULE_LICENSE("GPL v2"); 695