ses.c 16 KB

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