xref: /openbmc/linux/drivers/scsi/ses.c (revision e4ec7989)
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