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