This source file includes following definitions.
- ses_match
- ses_attach
- ses_detach
- ses_read_config
- ses_read_status
- ses_make_sensors
- ses_refresh_sensors
- ses_ioctl
- ses_write_config
- ses_bio_blink
- ses_psu2sensor
- ses_cool2sensor
- ses_temp2sensor
- ses_dump_enc_desc
- ses_dump_enc_string
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include "bio.h"
20
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 #include <sys/device.h>
24 #include <sys/scsiio.h>
25 #include <sys/malloc.h>
26 #include <sys/proc.h>
27 #include <sys/rwlock.h>
28 #include <sys/queue.h>
29 #include <sys/sensors.h>
30
31 #if NBIO > 0
32 #include <dev/biovar.h>
33 #endif
34
35 #include <scsi/scsi_all.h>
36 #include <scsi/scsiconf.h>
37
38 #include <scsi/ses.h>
39
40 #ifdef SES_DEBUG
41 #define DPRINTF(x...) do { if (sesdebug) printf(x); } while (0)
42 #define DPRINTFN(n, x...) do { if (sesdebug > (n)) printf(x); } while (0)
43 int sesdebug = 2;
44 #else
45 #define DPRINTF(x...)
46 #define DPRINTFN(n,x...)
47 #endif
48
49 int ses_match(struct device *, void *, void *);
50 void ses_attach(struct device *, struct device *, void *);
51 int ses_detach(struct device *, int);
52
53 struct ses_sensor {
54 struct ksensor se_sensor;
55 u_int8_t se_type;
56 struct ses_status *se_stat;
57
58 TAILQ_ENTRY(ses_sensor) se_entry;
59 };
60
61 #if NBIO > 0
62 struct ses_slot {
63 struct ses_status *sl_stat;
64
65 TAILQ_ENTRY(ses_slot) sl_entry;
66 };
67 #endif
68
69 struct ses_softc {
70 struct device sc_dev;
71 struct scsi_link *sc_link;
72 struct rwlock sc_lock;
73
74 enum {
75 SES_ENC_STD,
76 SES_ENC_DELL
77 } sc_enctype;
78
79 u_char *sc_buf;
80 ssize_t sc_buflen;
81
82 #if NBIO > 0
83 TAILQ_HEAD(, ses_slot) sc_slots;
84 #endif
85 TAILQ_HEAD(, ses_sensor) sc_sensors;
86 struct ksensordev sc_sensordev;
87 struct sensor_task *sc_sensortask;
88 };
89
90 struct cfattach ses_ca = {
91 sizeof(struct ses_softc), ses_match, ses_attach, ses_detach
92 };
93
94 struct cfdriver ses_cd = {
95 NULL, "ses", DV_DULL
96 };
97
98 #define DEVNAME(s) ((s)->sc_dev.dv_xname)
99
100 #define SES_BUFLEN 2048
101
102 int ses_read_config(struct ses_softc *);
103 int ses_read_status(struct ses_softc *);
104 int ses_make_sensors(struct ses_softc *, struct ses_type_desc *, int);
105 void ses_refresh_sensors(void *);
106
107 #if NBIO > 0
108 int ses_ioctl(struct device *, u_long, caddr_t);
109 int ses_write_config(struct ses_softc *);
110 int ses_bio_blink(struct ses_softc *, struct bioc_blink *);
111 #endif
112
113 void ses_psu2sensor(struct ses_softc *, struct ses_sensor *);
114 void ses_cool2sensor(struct ses_softc *, struct ses_sensor *);
115 void ses_temp2sensor(struct ses_softc *, struct ses_sensor *);
116
117 #ifdef SES_DEBUG
118 void ses_dump_enc_desc(struct ses_enc_desc *);
119 char *ses_dump_enc_string(u_char *, ssize_t);
120 #endif
121
122 int
123 ses_match(struct device *parent, void *match, void *aux)
124 {
125 struct scsi_attach_args *sa = aux;
126 struct scsi_inquiry_data *inq = sa->sa_inqbuf;
127
128 if (inq == NULL)
129 return (0);
130
131 if ((inq->device & SID_TYPE) == T_ENCLOSURE &&
132 SCSISPC(inq->version) >= 2)
133 return (2);
134
135
136 if ((inq->device & SID_TYPE) == T_PROCESSOR &&
137 SCSISPC(inq->version) == 3)
138 return (3);
139
140 return (0);
141 }
142
143 void
144 ses_attach(struct device *parent, struct device *self, void *aux)
145 {
146 struct ses_softc *sc = (struct ses_softc *)self;
147 struct scsi_attach_args *sa = aux;
148 char vendor[33];
149 struct ses_sensor *sensor;
150 #if NBIO > 0
151 struct ses_slot *slot;
152 #endif
153
154 sc->sc_link = sa->sa_sc_link;
155 sa->sa_sc_link->device_softc = sc;
156 rw_init(&sc->sc_lock, DEVNAME(sc));
157
158 scsi_strvis(vendor, sc->sc_link->inqdata.vendor,
159 sizeof(sc->sc_link->inqdata.vendor));
160 if (strncasecmp(vendor, "Dell", sizeof(vendor)) == 0)
161 sc->sc_enctype = SES_ENC_DELL;
162 else
163 sc->sc_enctype = SES_ENC_STD;
164
165 printf("\n");
166
167 if (ses_read_config(sc) != 0) {
168 printf("%s: unable to read enclosure configuration\n",
169 DEVNAME(sc));
170 return;
171 }
172
173 if (!TAILQ_EMPTY(&sc->sc_sensors)) {
174 sc->sc_sensortask = sensor_task_register(sc,
175 ses_refresh_sensors, 10);
176 if (sc->sc_sensortask == NULL) {
177 printf("%s: unable to register update task\n",
178 DEVNAME(sc));
179 while (!TAILQ_EMPTY(&sc->sc_sensors)) {
180 sensor = TAILQ_FIRST(&sc->sc_sensors);
181 TAILQ_REMOVE(&sc->sc_sensors, sensor,
182 se_entry);
183 free(sensor, M_DEVBUF);
184 }
185 } else {
186 TAILQ_FOREACH(sensor, &sc->sc_sensors, se_entry)
187 sensor_attach(&sc->sc_sensordev,
188 &sensor->se_sensor);
189 sensordev_install(&sc->sc_sensordev);
190 }
191 }
192
193 #if NBIO > 0
194 if (!TAILQ_EMPTY(&sc->sc_slots) &&
195 bio_register(self, ses_ioctl) != 0) {
196 printf("%s: unable to register ioctl\n", DEVNAME(sc));
197 while (!TAILQ_EMPTY(&sc->sc_slots)) {
198 slot = TAILQ_FIRST(&sc->sc_slots);
199 TAILQ_REMOVE(&sc->sc_slots, slot, sl_entry);
200 free(slot, M_DEVBUF);
201 }
202 }
203 #endif
204
205 if (TAILQ_EMPTY(&sc->sc_sensors)
206 #if NBIO > 0
207 && TAILQ_EMPTY(&sc->sc_slots)
208 #endif
209 ) {
210 free(sc->sc_buf, M_DEVBUF);
211 sc->sc_buf = NULL;
212 }
213 }
214
215 int
216 ses_detach(struct device *self, int flags)
217 {
218 struct ses_softc *sc = (struct ses_softc *)self;
219 struct ses_sensor *sensor;
220 #if NBIO > 0
221 struct ses_slot *slot;
222 #endif
223
224 rw_enter_write(&sc->sc_lock);
225
226 #if NBIO > 0
227 if (!TAILQ_EMPTY(&sc->sc_slots)) {
228 bio_unregister(self);
229 while (!TAILQ_EMPTY(&sc->sc_slots)) {
230 slot = TAILQ_FIRST(&sc->sc_slots);
231 TAILQ_REMOVE(&sc->sc_slots, slot, sl_entry);
232 free(slot, M_DEVBUF);
233 }
234 }
235 #endif
236
237 if (!TAILQ_EMPTY(&sc->sc_sensors)) {
238 sensordev_deinstall(&sc->sc_sensordev);
239 sensor_task_unregister(sc->sc_sensortask);
240
241 while (!TAILQ_EMPTY(&sc->sc_sensors)) {
242 sensor = TAILQ_FIRST(&sc->sc_sensors);
243 sensor_detach(&sc->sc_sensordev, &sensor->se_sensor);
244 TAILQ_REMOVE(&sc->sc_sensors, sensor, se_entry);
245 free(sensor, M_DEVBUF);
246 }
247 }
248
249 if (sc->sc_buf != NULL)
250 free(sc->sc_buf, M_DEVBUF);
251
252 rw_exit_write(&sc->sc_lock);
253
254 return (0);
255 }
256
257 int
258 ses_read_config(struct ses_softc *sc)
259 {
260 struct ses_scsi_diag cmd;
261 int flags;
262
263 u_char *buf, *p;
264
265 struct ses_config_hdr *cfg;
266 struct ses_enc_hdr *enc;
267 #ifdef SES_DEBUG
268 struct ses_enc_desc *desc;
269 #endif
270 struct ses_type_desc *tdh, *tdlist;
271
272 int i, ntypes = 0, nelems = 0;
273
274 buf = malloc(SES_BUFLEN, M_DEVBUF, M_NOWAIT);
275 if (buf == NULL)
276 return (1);
277
278 memset(buf, 0, SES_BUFLEN);
279 memset(&cmd, 0, sizeof(cmd));
280 cmd.opcode = RECEIVE_DIAGNOSTIC;
281 cmd.flags |= SES_DIAG_PCV;
282 cmd.pgcode = SES_PAGE_CONFIG;
283 cmd.length = htobe16(SES_BUFLEN);
284 flags = SCSI_DATA_IN;
285 #ifndef SCSIDEBUG
286 flags |= SCSI_SILENT;
287 #endif
288
289 if (cold)
290 flags |= SCSI_AUTOCONF;
291
292 if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd,
293 sizeof(cmd), buf, SES_BUFLEN, 2, 3000, NULL, flags) != 0) {
294 free(buf, M_DEVBUF);
295 return (1);
296 }
297
298 cfg = (struct ses_config_hdr *)buf;
299 if (cfg->pgcode != cmd.pgcode || betoh16(cfg->length) > SES_BUFLEN) {
300 free(buf, M_DEVBUF);
301 return (1);
302 }
303
304 DPRINTF("%s: config: n_subenc: %d length: %d\n", DEVNAME(sc),
305 cfg->n_subenc, betoh16(cfg->length));
306
307 p = buf + SES_CFG_HDRLEN;
308 for (i = 0; i <= cfg->n_subenc; i++) {
309 enc = (struct ses_enc_hdr *)p;
310 #ifdef SES_DEBUG
311 DPRINTF("%s: enclosure %d enc_id: 0x%02x n_types: %d\n",
312 DEVNAME(sc), i, enc->enc_id, enc->n_types);
313 desc = (struct ses_enc_desc *)(p + SES_ENC_HDRLEN);
314 ses_dump_enc_desc(desc);
315 #endif
316
317 ntypes += enc->n_types;
318
319 p += SES_ENC_HDRLEN + enc->vendor_len;
320 }
321
322 tdlist = (struct ses_type_desc *)p;
323
324 for (i = 0; i < ntypes; i++) {
325 tdh = (struct ses_type_desc *)p;
326 DPRINTF("%s: td %d subenc_id: %d type 0x%02x n_elem: %d\n",
327 DEVNAME(sc), i, tdh->subenc_id, tdh->type, tdh->n_elem);
328
329 nelems += tdh->n_elem;
330
331 p += SES_TYPE_DESCLEN;
332 }
333
334 #ifdef SES_DEBUG
335 for (i = 0; i < ntypes; i++) {
336 DPRINTF("%s: td %d '%s'\n", DEVNAME(sc), i,
337 ses_dump_enc_string(p, tdlist[i].desc_len));
338
339 p += tdlist[i].desc_len;
340 }
341 #endif
342
343 sc->sc_buflen = SES_STAT_LEN(ntypes, nelems);
344 sc->sc_buf = malloc(sc->sc_buflen, M_DEVBUF, M_NOWAIT);
345 if (sc->sc_buf == NULL) {
346 free(buf, M_DEVBUF);
347 return (1);
348 }
349
350
351 if (ses_make_sensors(sc, tdlist, ntypes) != 0) {
352 free(buf, M_DEVBUF);
353 free(sc->sc_buf, M_DEVBUF);
354 return (1);
355 }
356
357 free(buf, M_DEVBUF);
358 return (0);
359 }
360
361 int
362 ses_read_status(struct ses_softc *sc)
363 {
364 struct ses_scsi_diag cmd;
365 int flags;
366
367 memset(&cmd, 0, sizeof(cmd));
368 cmd.opcode = RECEIVE_DIAGNOSTIC;
369 cmd.flags |= SES_DIAG_PCV;
370 cmd.pgcode = SES_PAGE_STATUS;
371 cmd.length = htobe16(sc->sc_buflen);
372 flags = SCSI_DATA_IN;
373 #ifndef SCSIDEBUG
374 flags |= SCSI_SILENT;
375 #endif
376 if (cold)
377 flags |= SCSI_AUTOCONF;
378
379 if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd,
380 sizeof(cmd), sc->sc_buf, sc->sc_buflen, 2, 3000, NULL, flags) != 0)
381 return (1);
382
383 return (0);
384 }
385
386 int
387 ses_make_sensors(struct ses_softc *sc, struct ses_type_desc *types, int ntypes)
388 {
389 struct ses_status *status;
390 struct ses_sensor *sensor;
391 #if NBIO > 0
392 struct ses_slot *slot;
393 #endif
394 enum sensor_type stype;
395 char *fmt;
396 int i, j;
397
398 if (ses_read_status(sc) != 0)
399 return (1);
400
401 strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
402 sizeof(sc->sc_sensordev.xname));
403
404 TAILQ_INIT(&sc->sc_sensors);
405 #if NBIO > 0
406 TAILQ_INIT(&sc->sc_slots);
407 #endif
408
409 status = (struct ses_status *)(sc->sc_buf + SES_STAT_HDRLEN);
410 for (i = 0; i < ntypes; i++) {
411
412 DPRINTFN(1, "%s: %3d:- 0x%02x 0x%02x%02x%02x type: 0x%02x\n",
413 DEVNAME(sc), i, status->com, status->f1, status->f2,
414 status->f3, types[i].type);
415
416 for (j = 0; j < types[i].n_elem; j++) {
417
418 status++;
419
420 DPRINTFN(1, "%s: %3d:%-3d 0x%02x 0x%02x%02x%02x\n",
421 DEVNAME(sc), i, j, status->com, status->f1,
422 status->f2, status->f3);
423
424 if (SES_STAT_CODE(status->com) == SES_STAT_CODE_NOTINST)
425 continue;
426
427 switch (types[i].type) {
428 #if NBIO > 0
429 case SES_T_DEVICE:
430 slot = malloc(sizeof(struct ses_slot),
431 M_DEVBUF, M_NOWAIT);
432 if (slot == NULL)
433 goto error;
434
435 memset(slot, 0, sizeof(struct ses_slot));
436 slot->sl_stat = status;
437
438 TAILQ_INSERT_TAIL(&sc->sc_slots, slot,
439 sl_entry);
440
441 continue;
442 #endif
443
444 case SES_T_POWERSUPPLY:
445 stype = SENSOR_INDICATOR;
446 fmt = "PSU";
447 break;
448
449 case SES_T_COOLING:
450 stype = SENSOR_PERCENT;
451 fmt = "Fan";
452 break;
453
454 case SES_T_TEMP:
455 stype = SENSOR_TEMP;
456 fmt = "";
457 break;
458
459 default:
460 continue;
461 }
462
463 sensor = malloc(sizeof(struct ses_sensor), M_DEVBUF,
464 M_NOWAIT);
465 if (sensor == NULL)
466 goto error;
467
468 memset(sensor, 0, sizeof(struct ses_sensor));
469 sensor->se_type = types[i].type;
470 sensor->se_stat = status;
471 sensor->se_sensor.type = stype;
472 strlcpy(sensor->se_sensor.desc, fmt,
473 sizeof(sensor->se_sensor.desc));
474
475 TAILQ_INSERT_TAIL(&sc->sc_sensors, sensor, se_entry);
476 }
477
478
479 status++;
480 }
481
482 return (0);
483 error:
484 #if NBIO > 0
485 while (!TAILQ_EMPTY(&sc->sc_slots)) {
486 slot = TAILQ_FIRST(&sc->sc_slots);
487 TAILQ_REMOVE(&sc->sc_slots, slot, sl_entry);
488 free(slot, M_DEVBUF);
489 }
490 #endif
491 while (!TAILQ_EMPTY(&sc->sc_sensors)) {
492 sensor = TAILQ_FIRST(&sc->sc_sensors);
493 TAILQ_REMOVE(&sc->sc_sensors, sensor, se_entry);
494 free(sensor, M_DEVBUF);
495 }
496 return (1);
497 }
498
499 void
500 ses_refresh_sensors(void *arg)
501 {
502 struct ses_softc *sc = (struct ses_softc *)arg;
503 struct ses_sensor *sensor;
504 int ret = 0;
505
506 rw_enter_write(&sc->sc_lock);
507
508 if (ses_read_status(sc) != 0) {
509 rw_exit_write(&sc->sc_lock);
510 return;
511 }
512
513 TAILQ_FOREACH(sensor, &sc->sc_sensors, se_entry) {
514 DPRINTFN(10, "%s: %s 0x%02x 0x%02x%02x%02x\n", DEVNAME(sc),
515 sensor->se_sensor.desc, sensor->se_stat->com,
516 sensor->se_stat->f1, sensor->se_stat->f2,
517 sensor->se_stat->f3);
518
519 switch (SES_STAT_CODE(sensor->se_stat->com)) {
520 case SES_STAT_CODE_OK:
521 sensor->se_sensor.status = SENSOR_S_OK;
522 break;
523
524 case SES_STAT_CODE_CRIT:
525 case SES_STAT_CODE_UNREC:
526 sensor->se_sensor.status = SENSOR_S_CRIT;
527 break;
528
529 case SES_STAT_CODE_NONCRIT:
530 sensor->se_sensor.status = SENSOR_S_WARN;
531 break;
532
533 case SES_STAT_CODE_NOTINST:
534 case SES_STAT_CODE_UNKNOWN:
535 case SES_STAT_CODE_NOTAVAIL:
536 sensor->se_sensor.status = SENSOR_S_UNKNOWN;
537 break;
538 }
539
540 switch (sensor->se_type) {
541 case SES_T_POWERSUPPLY:
542 ses_psu2sensor(sc, sensor);
543 break;
544
545 case SES_T_COOLING:
546 ses_cool2sensor(sc, sensor);
547 break;
548
549 case SES_T_TEMP:
550 ses_temp2sensor(sc, sensor);
551 break;
552
553 default:
554 ret = 1;
555 break;
556 }
557 }
558
559 rw_exit_write(&sc->sc_lock);
560
561 if (ret)
562 printf("%s: error in sensor data\n", DEVNAME(sc));
563 }
564
565 #if NBIO > 0
566 int
567 ses_ioctl(struct device *dev, u_long cmd, caddr_t addr)
568 {
569 struct ses_softc *sc = (struct ses_softc *)dev;
570 int error = 0;
571
572 switch (cmd) {
573 case BIOCBLINK:
574 error = ses_bio_blink(sc, (struct bioc_blink *)addr);
575 break;
576
577 default:
578 error = EINVAL;
579 break;
580 }
581
582 return (error);
583 }
584
585 int
586 ses_write_config(struct ses_softc *sc)
587 {
588 struct ses_scsi_diag cmd;
589 int flags;
590
591 memset(&cmd, 0, sizeof(cmd));
592 cmd.opcode = SEND_DIAGNOSTIC;
593 cmd.flags |= SES_DIAG_PF;
594 cmd.length = htobe16(sc->sc_buflen);
595 flags = SCSI_DATA_OUT;
596 #ifndef SCSIDEBUG
597 flags |= SCSI_SILENT;
598 #endif
599
600 if (cold)
601 flags |= SCSI_AUTOCONF;
602
603 if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd,
604 sizeof(cmd), sc->sc_buf, sc->sc_buflen, 2, 3000, NULL, flags) != 0)
605 return (1);
606
607 return (0);
608 }
609
610 int
611 ses_bio_blink(struct ses_softc *sc, struct bioc_blink *blink)
612 {
613 struct ses_slot *slot;
614
615 rw_enter_write(&sc->sc_lock);
616
617 if (ses_read_status(sc) != 0) {
618 rw_exit_write(&sc->sc_lock);
619 return (EIO);
620 }
621
622 TAILQ_FOREACH(slot, &sc->sc_slots, sl_entry) {
623 if (slot->sl_stat->f1 == blink->bb_target)
624 break;
625 }
626
627 if (slot == TAILQ_END(&sc->sc_slots)) {
628 rw_exit_write(&sc->sc_lock);
629 return (EINVAL);
630 }
631
632 DPRINTFN(3, "%s: 0x%02x 0x%02x 0x%02x 0x%02x\n", DEVNAME(sc),
633 slot->sl_stat->com, slot->sl_stat->f1, slot->sl_stat->f2,
634 slot->sl_stat->f3);
635
636 slot->sl_stat->com = SES_STAT_SELECT;
637 slot->sl_stat->f2 &= SES_C_DEV_F2MASK;
638 slot->sl_stat->f3 &= SES_C_DEV_F3MASK;
639
640 switch (blink->bb_status) {
641 case BIOC_SBUNBLINK:
642 slot->sl_stat->f2 &= ~SES_C_DEV_IDENT;
643 break;
644
645 case BIOC_SBBLINK:
646 slot->sl_stat->f2 |= SES_C_DEV_IDENT;
647 break;
648
649 default:
650 rw_exit_write(&sc->sc_lock);
651 return (EINVAL);
652 }
653
654 DPRINTFN(3, "%s: 0x%02x 0x%02x 0x%02x 0x%02x\n", DEVNAME(sc),
655 slot->sl_stat->com, slot->sl_stat->f1, slot->sl_stat->f2,
656 slot->sl_stat->f3);
657
658 if (ses_write_config(sc) != 0) {
659 rw_exit_write(&sc->sc_lock);
660 return (EIO);
661 }
662
663 rw_exit_write(&sc->sc_lock);
664
665 return (0);
666 }
667 #endif
668
669 void
670 ses_psu2sensor(struct ses_softc *sc, struct ses_sensor *s)
671 {
672 s->se_sensor.value = SES_S_PSU_OFF(s->se_stat) ? 0 : 1;
673 }
674
675 void
676 ses_cool2sensor(struct ses_softc *sc, struct ses_sensor *s)
677 {
678 switch (sc->sc_enctype) {
679 case SES_ENC_STD:
680 switch (SES_S_COOL_CODE(s->se_stat)) {
681 case SES_S_COOL_C_STOPPED:
682 s->se_sensor.value = 0;
683 break;
684 case SES_S_COOL_C_LOW1:
685 case SES_S_COOL_C_LOW2:
686 case SES_S_COOL_C_LOW3:
687 s->se_sensor.value = 33333;
688 break;
689 case SES_S_COOL_C_INTER:
690 case SES_S_COOL_C_HI3:
691 case SES_S_COOL_C_HI2:
692 s->se_sensor.value = 66666;
693 break;
694 case SES_S_COOL_C_HI1:
695 s->se_sensor.value = 100000;
696 break;
697 }
698 break;
699
700
701 case SES_ENC_DELL:
702 switch (SES_S_COOL_CODE(s->se_stat)) {
703 case SES_S_COOL_C_STOPPED:
704 s->se_sensor.value = 0;
705 break;
706 case SES_S_COOL_C_LOW1:
707 s->se_sensor.value = 33333;
708 break;
709 case SES_S_COOL_C_LOW2:
710 s->se_sensor.value = 66666;
711 break;
712 case SES_S_COOL_C_LOW3:
713 case SES_S_COOL_C_INTER:
714 case SES_S_COOL_C_HI3:
715 case SES_S_COOL_C_HI2:
716 case SES_S_COOL_C_HI1:
717 s->se_sensor.value = 100000;
718 break;
719 }
720 break;
721 }
722 }
723
724 void
725 ses_temp2sensor(struct ses_softc *sc, struct ses_sensor *s)
726 {
727 s->se_sensor.value = (int64_t)SES_S_TEMP(s->se_stat);
728 s->se_sensor.value += SES_S_TEMP_OFFSET;
729 s->se_sensor.value *= 1000000;
730 s->se_sensor.value += 273150000;
731 }
732
733 #ifdef SES_DEBUG
734 void
735 ses_dump_enc_desc(struct ses_enc_desc *desc)
736 {
737 char str[32];
738
739 #if 0
740
741 memset(str, 0, sizeof(str));
742 memcpy(str, desc->logical_id, sizeof(desc->logical_id));
743 DPRINTF("logical_id: %s", str);
744 #endif
745
746 memset(str, 0, sizeof(str));
747 memcpy(str, desc->vendor_id, sizeof(desc->vendor_id));
748 DPRINTF(" vendor_id: %s", str);
749
750 memset(str, 0, sizeof(str));
751 memcpy(str, desc->prod_id, sizeof(desc->prod_id));
752 DPRINTF(" prod_id: %s", str);
753
754 memset(str, 0, sizeof(str));
755 memcpy(str, desc->prod_rev, sizeof(desc->prod_rev));
756 DPRINTF(" prod_rev: %s\n", str);
757 }
758
759 char *
760 ses_dump_enc_string(u_char *buf, ssize_t len)
761 {
762 static char str[256];
763
764 memset(str, 0, sizeof(str));
765 if (len > 0)
766 memcpy(str, buf, len);
767
768 return (str);
769 }
770 #endif