Merge branch 'fix/asoc' into for-linus
[pandora-kernel.git] / drivers / scsi / ses.c
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");