xref: /openbmc/linux/drivers/scsi/ses.c (revision b04b4f78)
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 
35 struct 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 
44 struct ses_component {
45 	u64 addr;
46 	unsigned char *desc;
47 };
48 
49 static 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 
67 static 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, NULL);
81 }
82 
83 static 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, NULL);
99 	if (result)
100 		sdev_printk(KERN_ERR, sdev, "SEND DIAGNOSTIC result: %8x\n",
101 			    result);
102 	return result;
103 }
104 
105 static 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 
136 static 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 
160 static 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 
170 static 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 
191 static 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 
201 static 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 
211 static 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 
231 static 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 
253 static 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 
262 struct ses_host_edev {
263 	struct Scsi_Host *shost;
264 	struct enclosure_device *edev;
265 };
266 
267 #if 0
268 int ses_match_host(struct enclosure_device *edev, void *data)
269 {
270 	struct ses_host_edev *sed = data;
271 	struct scsi_device *sdev;
272 
273 	if (!scsi_is_sdev_device(edev->edev.parent))
274 		return 0;
275 
276 	sdev = to_scsi_device(edev->edev.parent);
277 
278 	if (sdev->host != sed->shost)
279 		return 0;
280 
281 	sed->edev = edev;
282 	return 1;
283 }
284 #endif  /*  0  */
285 
286 static void ses_process_descriptor(struct enclosure_component *ecomp,
287 				   unsigned char *desc)
288 {
289 	int eip = desc[0] & 0x10;
290 	int invalid = desc[0] & 0x80;
291 	enum scsi_protocol proto = desc[0] & 0x0f;
292 	u64 addr = 0;
293 	struct ses_component *scomp = ecomp->scratch;
294 	unsigned char *d;
295 
296 	scomp->desc = desc;
297 
298 	if (invalid)
299 		return;
300 
301 	switch (proto) {
302 	case SCSI_PROTOCOL_SAS:
303 		if (eip)
304 			d = desc + 8;
305 		else
306 			d = desc + 4;
307 		/* only take the phy0 addr */
308 		addr = (u64)d[12] << 56 |
309 			(u64)d[13] << 48 |
310 			(u64)d[14] << 40 |
311 			(u64)d[15] << 32 |
312 			(u64)d[16] << 24 |
313 			(u64)d[17] << 16 |
314 			(u64)d[18] << 8 |
315 			(u64)d[19];
316 		break;
317 	default:
318 		/* FIXME: Need to add more protocols than just SAS */
319 		break;
320 	}
321 	scomp->addr = addr;
322 }
323 
324 struct efd {
325 	u64 addr;
326 	struct device *dev;
327 };
328 
329 static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
330 				      void *data)
331 {
332 	struct efd *efd = data;
333 	int i;
334 	struct ses_component *scomp;
335 
336 	if (!edev->component[0].scratch)
337 		return 0;
338 
339 	for (i = 0; i < edev->components; i++) {
340 		scomp = edev->component[i].scratch;
341 		if (scomp->addr != efd->addr)
342 			continue;
343 
344 		enclosure_add_device(edev, i, efd->dev);
345 		return 1;
346 	}
347 	return 0;
348 }
349 
350 static void ses_match_to_enclosure(struct enclosure_device *edev,
351 				   struct scsi_device *sdev)
352 {
353 	unsigned char *buf;
354 	unsigned char *desc;
355 	unsigned int vpd_len;
356 	struct efd efd = {
357 		.addr = 0,
358 	};
359 
360 	buf = scsi_get_vpd_page(sdev, 0x83);
361 	if (!buf)
362 		return;
363 
364 	vpd_len = ((buf[2] << 8) | buf[3]) + 4;
365 
366 	desc = buf + 4;
367 	while (desc < buf + vpd_len) {
368 		enum scsi_protocol proto = desc[0] >> 4;
369 		u8 code_set = desc[0] & 0x0f;
370 		u8 piv = desc[1] & 0x80;
371 		u8 assoc = (desc[1] & 0x30) >> 4;
372 		u8 type = desc[1] & 0x0f;
373 		u8 len = desc[3];
374 
375 		if (piv && code_set == 1 && assoc == 1
376 		    && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8)
377 			efd.addr = (u64)desc[4] << 56 |
378 				(u64)desc[5] << 48 |
379 				(u64)desc[6] << 40 |
380 				(u64)desc[7] << 32 |
381 				(u64)desc[8] << 24 |
382 				(u64)desc[9] << 16 |
383 				(u64)desc[10] << 8 |
384 				(u64)desc[11];
385 
386 		desc += len + 4;
387 	}
388 	if (!efd.addr)
389 		goto free;
390 
391 	efd.dev = &sdev->sdev_gendev;
392 
393 	enclosure_for_each_device(ses_enclosure_find_by_addr, &efd);
394  free:
395 	kfree(buf);
396 }
397 
398 #define INIT_ALLOC_SIZE 32
399 
400 static int ses_intf_add(struct device *cdev,
401 			struct class_interface *intf)
402 {
403 	struct scsi_device *sdev = to_scsi_device(cdev->parent);
404 	struct scsi_device *tmp_sdev;
405 	unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr = NULL,
406 		*addl_desc_ptr = NULL;
407 	struct ses_device *ses_dev;
408 	u32 result;
409 	int i, j, types, len, page7_len = 0, components = 0;
410 	int err = -ENOMEM;
411 	struct enclosure_device *edev;
412 	struct ses_component *scomp = NULL;
413 
414 	if (!scsi_device_enclosure(sdev)) {
415 		/* not an enclosure, but might be in one */
416 		edev = enclosure_find(&sdev->host->shost_gendev);
417 		if (edev) {
418 			ses_match_to_enclosure(edev, sdev);
419 			put_device(&edev->edev);
420 		}
421 		return -ENODEV;
422 	}
423 
424 	/* TYPE_ENCLOSURE prints a message in probe */
425 	if (sdev->type != TYPE_ENCLOSURE)
426 		sdev_printk(KERN_NOTICE, sdev, "Embedded Enclosure Device\n");
427 
428 	ses_dev = kzalloc(sizeof(*ses_dev), GFP_KERNEL);
429 	hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
430 	if (!hdr_buf || !ses_dev)
431 		goto err_init_free;
432 
433 	result = ses_recv_diag(sdev, 1, hdr_buf, INIT_ALLOC_SIZE);
434 	if (result)
435 		goto recv_failed;
436 
437 	if (hdr_buf[1] != 0) {
438 		/* FIXME: need subenclosure support; I've just never
439 		 * seen a device with subenclosures and it makes the
440 		 * traversal routines more complex */
441 		sdev_printk(KERN_ERR, sdev,
442 			"FIXME driver has no support for subenclosures (%d)\n",
443 			hdr_buf[1]);
444 		goto err_free;
445 	}
446 
447 	len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
448 	buf = kzalloc(len, GFP_KERNEL);
449 	if (!buf)
450 		goto err_free;
451 
452 	result = ses_recv_diag(sdev, 1, buf, len);
453 	if (result)
454 		goto recv_failed;
455 
456 	types = buf[10];
457 
458 	type_ptr = buf + 12 + buf[11];
459 
460 	for (i = 0; i < types; i++, type_ptr += 4) {
461 		if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
462 		    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE)
463 			components += type_ptr[1];
464 	}
465 	ses_dev->page1 = buf;
466 	ses_dev->page1_len = len;
467 	buf = NULL;
468 
469 	result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE);
470 	if (result)
471 		goto recv_failed;
472 
473 	len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
474 	buf = kzalloc(len, GFP_KERNEL);
475 	if (!buf)
476 		goto err_free;
477 
478 	/* make sure getting page 2 actually works */
479 	result = ses_recv_diag(sdev, 2, buf, len);
480 	if (result)
481 		goto recv_failed;
482 	ses_dev->page2 = buf;
483 	ses_dev->page2_len = len;
484 	buf = NULL;
485 
486 	/* The additional information page --- allows us
487 	 * to match up the devices */
488 	result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE);
489 	if (!result) {
490 
491 		len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
492 		buf = kzalloc(len, GFP_KERNEL);
493 		if (!buf)
494 			goto err_free;
495 
496 		result = ses_recv_diag(sdev, 10, buf, len);
497 		if (result)
498 			goto recv_failed;
499 		ses_dev->page10 = buf;
500 		ses_dev->page10_len = len;
501 		buf = NULL;
502 	}
503 
504 	scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
505 	if (!scomp)
506 		goto err_free;
507 
508 	edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev),
509 				  components, &ses_enclosure_callbacks);
510 	if (IS_ERR(edev)) {
511 		err = PTR_ERR(edev);
512 		goto err_free;
513 	}
514 
515 	edev->scratch = ses_dev;
516 	for (i = 0; i < components; i++)
517 		edev->component[i].scratch = scomp + i;
518 
519 	/* Page 7 for the descriptors is optional */
520 	result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE);
521 	if (result)
522 		goto simple_populate;
523 
524 	page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
525 	/* add 1 for trailing '\0' we'll use */
526 	buf = kzalloc(len + 1, GFP_KERNEL);
527 	if (!buf)
528 		goto simple_populate;
529 	result = ses_recv_diag(sdev, 7, buf, len);
530 	if (result) {
531  simple_populate:
532 		kfree(buf);
533 		buf = NULL;
534 		desc_ptr = NULL;
535 		addl_desc_ptr = NULL;
536 	} else {
537 		desc_ptr = buf + 8;
538 		len = (desc_ptr[2] << 8) + desc_ptr[3];
539 		/* skip past overall descriptor */
540 		desc_ptr += len + 4;
541 		if (ses_dev->page10)
542 			addl_desc_ptr = ses_dev->page10 + 8;
543 	}
544 	type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
545 	components = 0;
546 	for (i = 0; i < types; i++, type_ptr += 4) {
547 		for (j = 0; j < type_ptr[1]; j++) {
548 			char *name = NULL;
549 			struct enclosure_component *ecomp;
550 
551 			if (desc_ptr) {
552 				if (desc_ptr >= buf + page7_len) {
553 					desc_ptr = NULL;
554 				} else {
555 					len = (desc_ptr[2] << 8) + desc_ptr[3];
556 					desc_ptr += 4;
557 					/* Add trailing zero - pushes into
558 					 * reserved space */
559 					desc_ptr[len] = '\0';
560 					name = desc_ptr;
561 				}
562 			}
563 			if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
564 			    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
565 
566 				ecomp =	enclosure_component_register(edev,
567 							     components++,
568 							     type_ptr[0],
569 							     name);
570 
571 				if (!IS_ERR(ecomp) && addl_desc_ptr)
572 					ses_process_descriptor(ecomp,
573 							       addl_desc_ptr);
574 			}
575 			if (desc_ptr)
576 				desc_ptr += len;
577 
578 			if (addl_desc_ptr)
579 				addl_desc_ptr += addl_desc_ptr[1] + 2;
580 
581 		}
582 	}
583 	kfree(buf);
584 	kfree(hdr_buf);
585 
586 	/* see if there are any devices matching before
587 	 * we found the enclosure */
588 	shost_for_each_device(tmp_sdev, sdev->host) {
589 		if (tmp_sdev->lun != 0 || scsi_device_enclosure(tmp_sdev))
590 			continue;
591 		ses_match_to_enclosure(edev, tmp_sdev);
592 	}
593 
594 	return 0;
595 
596  recv_failed:
597 	sdev_printk(KERN_ERR, sdev, "Failed to get diagnostic page 0x%x\n",
598 		    result);
599 	err = -ENODEV;
600  err_free:
601 	kfree(buf);
602 	kfree(scomp);
603 	kfree(ses_dev->page10);
604 	kfree(ses_dev->page2);
605 	kfree(ses_dev->page1);
606  err_init_free:
607 	kfree(ses_dev);
608 	kfree(hdr_buf);
609 	sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n", err);
610 	return err;
611 }
612 
613 static int ses_remove(struct device *dev)
614 {
615 	return 0;
616 }
617 
618 static void ses_intf_remove(struct device *cdev,
619 			    struct class_interface *intf)
620 {
621 	struct scsi_device *sdev = to_scsi_device(cdev->parent);
622 	struct enclosure_device *edev;
623 	struct ses_device *ses_dev;
624 
625 	if (!scsi_device_enclosure(sdev))
626 		return;
627 
628 	edev = enclosure_find(cdev->parent);
629 	if (!edev)
630 		return;
631 
632 	ses_dev = edev->scratch;
633 	edev->scratch = NULL;
634 
635 	kfree(ses_dev->page10);
636 	kfree(ses_dev->page1);
637 	kfree(ses_dev->page2);
638 	kfree(ses_dev);
639 
640 	kfree(edev->component[0].scratch);
641 
642 	put_device(&edev->edev);
643 	enclosure_unregister(edev);
644 }
645 
646 static struct class_interface ses_interface = {
647 	.add_dev	= ses_intf_add,
648 	.remove_dev	= ses_intf_remove,
649 };
650 
651 static struct scsi_driver ses_template = {
652 	.owner			= THIS_MODULE,
653 	.gendrv = {
654 		.name		= "ses",
655 		.probe		= ses_probe,
656 		.remove		= ses_remove,
657 	},
658 };
659 
660 static int __init ses_init(void)
661 {
662 	int err;
663 
664 	err = scsi_register_interface(&ses_interface);
665 	if (err)
666 		return err;
667 
668 	err = scsi_register_driver(&ses_template.gendrv);
669 	if (err)
670 		goto out_unreg;
671 
672 	return 0;
673 
674  out_unreg:
675 	scsi_unregister_interface(&ses_interface);
676 	return err;
677 }
678 
679 static void __exit ses_exit(void)
680 {
681 	scsi_unregister_driver(&ses_template.gendrv);
682 	scsi_unregister_interface(&ses_interface);
683 }
684 
685 module_init(ses_init);
686 module_exit(ses_exit);
687 
688 MODULE_ALIAS_SCSI_DEVICE(TYPE_ENCLOSURE);
689 
690 MODULE_AUTHOR("James Bottomley");
691 MODULE_DESCRIPTION("SCSI Enclosure Services (ses) driver");
692 MODULE_LICENSE("GPL v2");
693