ses.c 17 KB

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