1 /* @(#)scsilog.c 1.25 10/12/19 Copyright 1998-2010 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)scsilog.c 1.25 10/12/19 Copyright 1998-2010 J. Schilling";
6 #endif
7 /*
8 * SCSI log page handling
9 *
10 * Copyright (c) 1998-2010 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include <schily/mconfig.h>
27
28 #include <schily/stdio.h>
29 #include <schily/standard.h>
30 #include <schily/utypes.h>
31 #include <schily/btorder.h>
32 #include <schily/schily.h>
33 #include <schily/nlsdefs.h>
34
35 #include <scg/scgcmd.h>
36 #include <scg/scsidefs.h>
37 #include <scg/scsireg.h>
38 #include <scg/scsitransp.h>
39
40 #include "scsilog.h"
41
42 extern int lverbose;
43
44 EXPORT int log_sense __PR((SCSI *scgp, caddr_t bp, int cnt, int page, int pc, int pp));
45 EXPORT BOOL has_log_page __PR((SCSI *scgp, int page, int pc));
46 EXPORT int get_log __PR((SCSI *scgp, caddr_t bp, int *lenp, int page, int pc, int pp));
47 EXPORT void print_logpages __PR((SCSI *scgp));
48
49 /*
50 * Currently not implemented: PPC, SP
51 */
52 EXPORT int
log_sense(scgp,bp,cnt,page,pc,pp)53 log_sense(scgp, bp, cnt, page, pc, pp)
54 SCSI *scgp;
55 caddr_t bp;
56 int cnt;
57 int page; /* Page code */
58 int pc; /* Page control */
59 int pp; /* Parameter Pointer */
60 {
61 register struct scg_cmd *scmd = scgp->scmd;
62
63 fillbytes(bp, cnt, '\0');
64 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
65 scmd->addr = bp;
66 scmd->size = cnt;
67 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
68 scmd->cdb_len = SC_G1_CDBLEN;
69 scmd->sense_len = CCS_SENSE_LEN;
70 scmd->cdb.g1_cdb.cmd = 0x4D;
71 scmd->cdb.g1_cdb.lun = scg_lun(scgp);
72 scmd->cdb.g1_cdb.addr[0] = (pc << 6) | (page & 0x3f);
73 i_to_2_byte(&scmd->cdb.cmd_cdb[5], pp);
74 g1_cdblen(&scmd->cdb.g1_cdb, cnt);
75
76 scgp->cmdname = "log sense";
77
78 if (scg_cmd(scgp) < 0)
79 return (-1);
80 if (scgp->verbose)
81 scg_prbytes(_("Log sense Data :"), (Uchar *)bp, cnt - scg_getresid(scgp));
82 return (0);
83 }
84
85 EXPORT BOOL
has_log_page(scgp,page,pc)86 has_log_page(scgp, page, pc)
87 SCSI *scgp;
88 int page;
89 int pc;
90 {
91 Uchar log[0x3F + sizeof (scsi_log_hdr)];
92 int len;
93 int i;
94 struct scsi_logpage_0 *sp = (struct scsi_logpage_0 *)log;
95
96 scgp->silent++;
97 if (log_sense(scgp, (caddr_t)log, sizeof (scsi_log_hdr), 0, pc, 0) < 0) {
98 scgp->silent--;
99 return (FALSE);
100 }
101
102 len = a_to_u_2_byte(sp->hdr.p_len);
103
104 if (log_sense(scgp, (caddr_t)log, len + sizeof (scsi_log_hdr), 0, pc, 0) < 0) {
105 scgp->silent--;
106 return (FALSE);
107 }
108 scgp->silent--;
109
110 len -= scg_getresid(scgp);
111
112 for (i = 0; i < len; i++) {
113 if (page == sp->p_code[i])
114 return (TRUE);
115 }
116 return (FALSE);
117 }
118
119 EXPORT int
get_log(scgp,bp,lenp,page,pc,pp)120 get_log(scgp, bp, lenp, page, pc, pp)
121 SCSI *scgp;
122 caddr_t bp;
123 int *lenp;
124 int page;
125 int pc;
126 int pp;
127 {
128 Uchar log[sizeof (scsi_log_hdr)];
129 scsi_log_hdr *hp = (scsi_log_hdr *)log;
130 int maxlen = *lenp;
131 int len;
132
133 if (log_sense(scgp, (caddr_t)log, sizeof (scsi_log_hdr), page, pc, pp) < 0)
134 return (-1);
135 len = a_to_u_2_byte(hp->p_len);
136 *lenp = len + sizeof (scsi_log_hdr);
137 if ((len + (int)sizeof (scsi_log_hdr)) > maxlen)
138 len = maxlen - sizeof (scsi_log_hdr);
139
140 if (log_sense(scgp, bp, len + sizeof (scsi_log_hdr), page, pc, pp) < 0)
141 return (-1);
142 return (0);
143 }
144
145 EXPORT void
print_logpages(scgp)146 print_logpages(scgp)
147 SCSI *scgp;
148 {
149 Uchar log[0x3F + sizeof (scsi_log_hdr)];
150 int len;
151 int i;
152 struct scsi_logpage_0 *sp = (struct scsi_logpage_0 *)log;
153
154 scgp->silent++;
155 if (log_sense(scgp, (caddr_t)log, sizeof (scsi_log_hdr), 0, LOG_CUMUL, 0) < 0) {
156 scgp->silent--;
157 return;
158 }
159
160 len = a_to_u_2_byte(sp->hdr.p_len);
161
162 if (log_sense(scgp, (caddr_t)log, len + sizeof (scsi_log_hdr), 0, LOG_CUMUL, 0) < 0) {
163 scgp->silent--;
164 return;
165 }
166 scgp->silent--;
167
168 len -= scg_getresid(scgp);
169
170 printf(_("Supported log pages:"));
171
172 for (i = 0; i < len; i++) {
173 printf(" %X", sp->p_code[i]);
174 }
175 printf("\n");
176 }
177