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