1 /* $OpenBSD: scsiconf.h,v 1.60 2005/06/24 23:39:18 krw Exp $ */
2 /* $NetBSD: scsiconf.h,v 1.35 1997/04/02 02:29:38 mycroft Exp $ */
3
4 /*
5 * Copyright (c) 1993, 1994, 1995 Charles Hannum. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Charles Hannum.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Originally written by Julian Elischer (julian@tfs.com)
35 * for TRW Financial Systems for use under the MACH(2.5) operating system.
36 *
37 * TRW Financial Systems, in accordance with their agreement with Carnegie
38 * Mellon University, makes this software available to CMU to distribute
39 * or use in any manner that they see fit as long as this message is kept with
40 * the software. For this reason TFS also grants any other persons or
41 * organisations permission to use or modify this software.
42 *
43 * TFS supplies this software to be publicly redistributed
44 * on the understanding that TFS is not responsible for the correct
45 * functioning of this software in any circumstances.
46 *
47 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
48 */
49
50 #ifndef SCSI_SCSICONF_H
51 #define SCSI_SCSICONF_H 1
52
53 typedef int boolean;
54
55 #include <sys/queue.h>
56 #include <sys/timeout.h>
57 #include <machine/cpu.h>
58 #include <scsi/scsi_debug.h>
59
60 /*
61 * The following documentation tries to describe the relationship between the
62 * various structures defined in this file:
63 *
64 * each adapter type has a scsi_adapter struct. This describes the adapter and
65 * identifies routines that can be called to use the adapter.
66 * each device type has a scsi_device struct. This describes the device and
67 * identifies routines that can be called to use the device.
68 * each existing device position (scsibus + target + lun)
69 * can be described by a scsi_link struct.
70 * Only scsi positions that actually have devices, have a scsi_link
71 * structure assigned. so in effect each device has scsi_link struct.
72 * The scsi_link structure contains information identifying both the
73 * device driver and the adapter driver for that position on that scsi bus,
74 * and can be said to 'link' the two.
75 * each individual scsi bus has an array that points to all the scsi_link
76 * structs associated with that scsi bus. Slots with no device have
77 * a NULL pointer.
78 * each individual device also knows the address of it's own scsi_link
79 * structure.
80 *
81 * -------------
82 *
83 * The key to all this is the scsi_link structure which associates all the
84 * other structures with each other in the correct configuration. The
85 * scsi_link is the connecting information that allows each part of the
86 * scsi system to find the associated other parts.
87 */
88
89 struct buf;
90 struct scsi_xfer;
91 struct scsi_link;
92
93 /*
94 * Temporary hack
95 */
96 extern int scsi_autoconf;
97
98 /*
99 * Specify which buses and targets must scan all LUNs, even when IDENTIFY does
100 * not seem to be working. Some devices (e.g. some external RAID devices) may
101 * seem to have non-functional IDENTIFY because they return identical INQUIRY
102 * data for all LUNs.
103 */
104 #ifndef SCSIFORCELUN_BUSES
105 #define SCSIFORCELUN_BUSES 0
106 #endif
107 #ifndef SCSIFORCELUN_TARGETS
108 #define SCSIFORCELUN_TARGETS 0
109 #endif
110
111 extern int scsiforcelun_buses, scsiforcelun_targets;
112
113 /*
114 * These entrypoints are called by the high-end drivers to get services from
115 * whatever low-end drivers they are attached to. Each adapter type has one
116 * of these statically allocated.
117 */
118 struct scsi_adapter {
119 int (*scsi_cmd)(struct scsi_xfer *);
120 void (*scsi_minphys)(struct buf *);
121 int (*open_target_lu)(void);
122 int (*close_target_lu)(void);
123 int (*ioctl)(struct scsi_link *, u_long cmd,
124 caddr_t addrp, int flag, struct proc *p);
125 };
126
127 /*
128 * return values for scsi_cmd()
129 */
130 #define SUCCESSFULLY_QUEUED 0
131 #define TRY_AGAIN_LATER 1
132 #define COMPLETE 2
133 #define ESCAPE_NOT_SUPPORTED 3
134
135 /*
136 * These entry points are called by the low-end drivers to get services from
137 * whatever high-end drivers they are attached to. Each device type has one
138 * of these statically allocated.
139 */
140 struct scsi_device {
141 int (*err_handler)(struct scsi_xfer *);
142 /* returns -1 to say err processing done */
143 void (*start)(void *);
144
145 int (*async)(void);
146 /*
147 * When called with `0' as the second argument, we expect status
148 * back from the upper-level driver. When called with a `1',
149 * we're simply notifying the upper-level driver that the command
150 * is complete and expect no status back.
151 */
152 void (*done)(struct scsi_xfer *);
153 };
154
155 /*
156 * This structure describes the connection between an adapter driver and
157 * a device driver, and is used by each to call services provided by
158 * the other, and to allow generic scsi glue code to call these services
159 * as well.
160 */
161 struct scsi_link {
162 u_int8_t scsi_version; /* SCSI-I, SCSI-II, etc. */
163 u_int8_t scsibus; /* the Nth scsibus */
164 u_int16_t target; /* targ of this dev */
165 u_int16_t lun; /* lun of this dev */
166 u_int16_t adapter_target; /* what are we on the scsi bus */
167 u_int16_t adapter_buswidth; /* 8 (regular) or 16 (wide). (0 becomes 8) */
168 u_int16_t openings; /* available operations */
169 u_int16_t active; /* operations in progress */
170 u_int16_t flags; /* flags that all devices have */
171 #define SDEV_REMOVABLE 0x0001 /* media is removable */
172 #define SDEV_MEDIA_LOADED 0x0002 /* device figures are still valid */
173 #define SDEV_WAITING 0x0004 /* a process is waiting for this */
174 #define SDEV_OPEN 0x0008 /* at least 1 open session */
175 #define SDEV_DBX 0x00f0 /* debugging flags (scsi_debug.h) */
176 #define SDEV_EJECTING 0x0100 /* eject on device close */
177 #define SDEV_ATAPI 0x0200 /* device is ATAPI */
178 #define SDEV_2NDBUS 0x0400 /* device is a 'second' bus device */
179 #define SDEV_UMASS 0x0800 /* device is UMASS SCSI */
180 u_int16_t quirks; /* per-device oddities */
181 #define SDEV_AUTOSAVE 0x0001 /* do implicit SAVEDATAPOINTER on disconnect */
182 #define SDEV_NOSYNC 0x0002 /* does not grok SDTR */
183 #define SDEV_NOWIDE 0x0004 /* does not grok WDTR */
184 #define SDEV_NOTAGS 0x0008 /* lies about having tagged queueing */
185 #define SDEV_NOSYNCCACHE 0x0100 /* no SYNCHRONIZE_CACHE */
186 #define ADEV_NOSENSE 0x0200 /* No request sense - ATAPI */
187 #define ADEV_LITTLETOC 0x0400 /* little-endian TOC - ATAPI */
188 #define ADEV_NOCAPACITY 0x0800 /* no READ CD CAPACITY */
189 #define ADEV_NOTUR 0x1000 /* No TEST UNIT READY */
190 #define ADEV_NODOORLOCK 0x2000 /* can't lock door */
191 #define SDEV_ONLYBIG 0x4000 /* always use READ_BIG and WRITE_BIG */
192 u_int8_t inquiry_flags; /* copy of flags from probe INQUIRY */
193 struct scsi_device *device; /* device entry points etc. */
194 void *device_softc; /* needed for call to foo_start */
195 struct scsi_adapter *adapter; /* adapter entry points etc. */
196 void *adapter_softc; /* needed for call to foo_scsi_cmd */
197 u_char luns;
198 struct scsi_inquiry_data inqdata; /* copy of INQUIRY data from probe */
199 };
200
201 int scsiprint(void *, const char *);
202
203 /*
204 * This describes matching information for scsi_inqmatch(). The more things
205 * match, the higher the configuration priority.
206 */
207 struct scsi_inquiry_pattern {
208 u_int8_t type;
209 boolean removable;
210 char *vendor;
211 char *product;
212 char *revision;
213 };
214
215 /*
216 * One of these is allocated and filled in for each scsi bus.
217 * It holds pointers to allow the scsi bus to get to the driver
218 * that is running each LUN on the bus.
219 * It also has a template entry which is the prototype struct
220 * supplied by the adapter driver. This is used to initialise
221 * the others, before they have the rest of the fields filled in.
222 */
223 struct scsibus_softc {
224 struct device sc_dev;
225 struct scsi_link *adapter_link; /* prototype supplied by adapter */
226 struct scsi_link ***sc_link;
227 u_int16_t sc_buswidth;
228 };
229
230 /*
231 * This is used to pass information from the high-level configuration code
232 * to the device-specific drivers.
233 */
234 struct scsibus_attach_args {
235 struct scsi_link *sa_sc_link;
236 struct scsi_inquiry_data *sa_inqbuf;
237 };
238
239 /*
240 * Each scsi transaction is fully described by one of these structures.
241 * It includes information about the source of the command and also the
242 * device and adapter for which the command is destined.
243 * (via the scsi_link structure)
244 */
245 struct scsi_xfer {
246 LIST_ENTRY(scsi_xfer) free_list;
247 int flags;
248 struct scsi_link *sc_link; /* all about our device and adapter */
249 int retries; /* the number of times to retry */
250 int timeout; /* in milliseconds */
251 struct scsi_generic *cmd; /* The scsi command to execute */
252 int cmdlen; /* how long it is */
253 u_char *data; /* dma address OR a uio address */
254 int datalen; /* data len (blank if uio) */
255 size_t resid; /* how much buffer was not touched */
256 int error; /* an error value */
257 struct buf *bp; /* If we need to associate with a buf */
258 struct scsi_sense_data sense; /* 32 bytes*/
259 /*
260 * Believe it or not, Some targets fall on the ground with
261 * anything but a certain sense length.
262 */
263 int req_sense_length; /* Explicit request sense length */
264 u_int8_t status; /* SCSI status */
265 struct scsi_generic cmdstore; /* stash the command in here */
266 /*
267 * timeout structure for hba's to use for a command
268 */
269 struct timeout stimeout;
270 };
271
272 /*
273 * Per-request Flag values
274 */
275 #define SCSI_NOSLEEP 0x00001 /* don't sleep */
276 #define SCSI_POLL 0x00002 /* poll for completion */
277 #define SCSI_AUTOCONF 0x00003 /* shorthand for SCSI_POLL | SCSI_NOSLEEP */
278 #define SCSI_USER 0x00004 /* Is a user cmd, call scsi_user_done */
279 #define ITSDONE 0x00008 /* the transfer is as done as it gets */
280 #define SCSI_SILENT 0x00020 /* don't announce NOT READY or MEDIA CHANGE */
281 #define SCSI_IGNORE_NOT_READY 0x00040 /* ignore NOT READY */
282 #define SCSI_IGNORE_MEDIA_CHANGE 0x00080 /* ignore MEDIA CHANGE */
283 #define SCSI_IGNORE_ILLEGAL_REQUEST 0x00100 /* ignore ILLEGAL REQUEST */
284 #define SCSI_RESET 0x00200 /* Reset the device in question */
285 #define SCSI_DATA_UIO 0x00400 /* The data address refers to a UIO */
286 #define SCSI_DATA_IN 0x00800 /* expect data to come INTO memory */
287 #define SCSI_DATA_OUT 0x01000 /* expect data to flow OUT of memory */
288 #define SCSI_TARGET 0x02000 /* This defines a TARGET mode op. */
289 #define SCSI_ESCAPE 0x04000 /* Escape operation */
290 #define SCSI_URGENT 0x08000 /* Urgent operation (e.g., HTAG) */
291 #define SCSI_PRIVATE 0xf0000 /* private to each HBA flags */
292
293 /*
294 * Escape op-codes. This provides an extensible setup for operations
295 * that are not scsi commands. They are intended for modal operations.
296 */
297
298 #define SCSI_OP_TARGET 0x0001
299 #define SCSI_OP_RESET 0x0002
300 #define SCSI_OP_BDINFO 0x0003
301
302 /*
303 * Error values an adapter driver may return
304 */
305 #define XS_NOERROR 0 /* there is no error, (sense is invalid) */
306 #define XS_SENSE 1 /* Check the returned sense for the error */
307 #define XS_DRIVER_STUFFUP 2 /* Driver failed to perform operation */
308 #define XS_SELTIMEOUT 3 /* The device timed out.. turned off? */
309 #define XS_TIMEOUT 4 /* The Timeout reported was caught by SW */
310 #define XS_BUSY 5 /* The device busy, try again later? */
311 #define XS_SHORTSENSE 6 /* Check the ATAPI sense for the error */
312 #define XS_RESET 8 /* bus was reset; possible retry command */
313
314 /*
315 * Possible retries numbers for scsi_test_unit_ready()
316 */
317 #define TEST_READY_RETRIES_DEFAULT 5
318 #define TEST_READY_RETRIES_CD 10
319 #define TEST_READY_RETRIES_TAPE 60
320
321 const void *scsi_inqmatch(struct scsi_inquiry_data *, const void *, int,
322 int, int *);
323
324 void scsi_init(void);
325 struct scsi_xfer *
326 scsi_get_xs(struct scsi_link *, int);
327 void scsi_free_xs(struct scsi_xfer *);
328 int scsi_execute_xs(struct scsi_xfer *);
329 u_long scsi_size(struct scsi_link *, int, u_int32_t *);
330 int scsi_test_unit_ready(struct scsi_link *, int, int);
331 int scsi_inquire(struct scsi_link *, struct scsi_inquiry_data *, int);
332 int scsi_prevent(struct scsi_link *, int, int);
333 int scsi_start(struct scsi_link *, int, int);
334 int scsi_mode_sense(struct scsi_link *, int, int, struct scsi_mode_header *,
335 size_t, int, int);
336 int scsi_mode_sense_big(struct scsi_link *, int, int,
337 struct scsi_mode_header_big *, size_t, int, int);
338 void * scsi_mode_sense_page(struct scsi_mode_header *, int);
339 void * scsi_mode_sense_big_page(struct scsi_mode_header_big *, int);
340 int scsi_do_mode_sense(struct scsi_link *, int,
341 struct scsi_mode_sense_buf *, void **, u_int32_t *, u_int64_t *,
342 u_int32_t *, int, int, int *);
343 int scsi_mode_select(struct scsi_link *, int, struct scsi_mode_header *,
344 int, int);
345 int scsi_mode_select_big(struct scsi_link *, int,
346 struct scsi_mode_header_big *, int, int);
347 void scsi_done(struct scsi_xfer *);
348 void scsi_user_done(struct scsi_xfer *);
349 int scsi_scsi_cmd(struct scsi_link *, struct scsi_generic *,
350 int cmdlen, u_char *data_addr, int datalen, int retries,
351 int timeout, struct buf *bp, int flags);
352 int scsi_do_ioctl(struct scsi_link *, dev_t, u_long, caddr_t,
353 int, struct proc *);
354 void sc_print_addr(struct scsi_link *);
355
356 void show_scsi_xs(struct scsi_xfer *);
357 void scsi_print_sense(struct scsi_xfer *);
358 void show_scsi_cmd(struct scsi_xfer *);
359 void show_mem(u_char *, int);
360 int scsi_probe_busses(int, int, int);
361 void scsi_strvis(u_char *, u_char *, int);
362
363 static __inline void _lto2b(u_int32_t val, u_int8_t *bytes);
364 static __inline void _lto3b(u_int32_t val, u_int8_t *bytes);
365 static __inline void _lto4b(u_int32_t val, u_int8_t *bytes);
366 static __inline void _lto8b(u_int64_t val, u_int8_t *bytes);
367 static __inline u_int32_t _2btol(u_int8_t *bytes);
368 static __inline u_int32_t _3btol(u_int8_t *bytes);
369 static __inline u_int32_t _4btol(u_int8_t *bytes);
370 static __inline u_int64_t _5btol(u_int8_t *bytes);
371 static __inline u_int64_t _8btol(u_int8_t *bytes);
372
373 static __inline void _lto2l(u_int32_t val, u_int8_t *bytes);
374 static __inline void _lto3l(u_int32_t val, u_int8_t *bytes);
375 static __inline void _lto4l(u_int32_t val, u_int8_t *bytes);
376 static __inline u_int32_t _2ltol(u_int8_t *bytes);
377 static __inline u_int32_t _3ltol(u_int8_t *bytes);
378 static __inline u_int32_t _4ltol(u_int8_t *bytes);
379
380 static __inline void
_lto2b(val,bytes)381 _lto2b(val, bytes)
382 u_int32_t val;
383 u_int8_t *bytes;
384 {
385
386 bytes[0] = (val >> 8) & 0xff;
387 bytes[1] = val & 0xff;
388 }
389
390 static __inline void
_lto3b(val,bytes)391 _lto3b(val, bytes)
392 u_int32_t val;
393 u_int8_t *bytes;
394 {
395
396 bytes[0] = (val >> 16) & 0xff;
397 bytes[1] = (val >> 8) & 0xff;
398 bytes[2] = val & 0xff;
399 }
400
401 static __inline void
_lto4b(val,bytes)402 _lto4b(val, bytes)
403 u_int32_t val;
404 u_int8_t *bytes;
405 {
406
407 bytes[0] = (val >> 24) & 0xff;
408 bytes[1] = (val >> 16) & 0xff;
409 bytes[2] = (val >> 8) & 0xff;
410 bytes[3] = val & 0xff;
411 }
412
413 static __inline void
_lto8b(val,bytes)414 _lto8b(val, bytes)
415 u_int64_t val;
416 u_int8_t *bytes;
417 {
418
419 bytes[0] = (val >> 56) & 0xff;
420 bytes[1] = (val >> 48) & 0xff;
421 bytes[2] = (val >> 40) & 0xff;
422 bytes[3] = (val >> 32) & 0xff;
423 bytes[4] = (val >> 24) & 0xff;
424 bytes[5] = (val >> 16) & 0xff;
425 bytes[6] = (val >> 8) & 0xff;
426 bytes[7] = val & 0xff;
427 }
428
429 static __inline u_int32_t
_2btol(bytes)430 _2btol(bytes)
431 u_int8_t *bytes;
432 {
433 u_int32_t rv;
434
435 rv = (bytes[0] << 8) | bytes[1];
436 return (rv);
437 }
438
439 static __inline u_int32_t
_3btol(bytes)440 _3btol(bytes)
441 u_int8_t *bytes;
442 {
443 u_int32_t rv;
444
445 rv = (bytes[0] << 16) | (bytes[1] << 8) | bytes[2];
446 return (rv);
447 }
448
449 static __inline u_int32_t
_4btol(bytes)450 _4btol(bytes)
451 u_int8_t *bytes;
452 {
453 u_int32_t rv;
454
455 rv = (bytes[0] << 24) | (bytes[1] << 16) |
456 (bytes[2] << 8) | bytes[3];
457 return (rv);
458 }
459
460 static __inline u_int64_t
_5btol(bytes)461 _5btol(bytes)
462 u_int8_t *bytes;
463 {
464 u_int64_t rv;
465
466 rv = ((u_int64_t)bytes[0] << 32) |
467 ((u_int64_t)bytes[1] << 24) |
468 ((u_int64_t)bytes[2] << 16) |
469 ((u_int64_t)bytes[3] << 8) |
470 (u_int64_t)bytes[4];
471 return (rv);
472 }
473
474 static __inline u_int64_t
_8btol(bytes)475 _8btol(bytes)
476 u_int8_t *bytes;
477 {
478 u_int64_t rv;
479
480 rv = (((u_int64_t)bytes[0]) << 56) |
481 (((u_int64_t)bytes[1]) << 48) |
482 (((u_int64_t)bytes[2]) << 40) |
483 (((u_int64_t)bytes[3]) << 32) |
484 (((u_int64_t)bytes[4]) << 24) |
485 (((u_int64_t)bytes[5]) << 16) |
486 (((u_int64_t)bytes[6]) << 8) |
487 ((u_int64_t)bytes[7]);
488 return (rv);
489 }
490
491 static __inline void
_lto2l(val,bytes)492 _lto2l(val, bytes)
493 u_int32_t val;
494 u_int8_t *bytes;
495 {
496
497 bytes[0] = val & 0xff;
498 bytes[1] = (val >> 8) & 0xff;
499 }
500
501 static __inline void
_lto3l(val,bytes)502 _lto3l(val, bytes)
503 u_int32_t val;
504 u_int8_t *bytes;
505 {
506
507 bytes[0] = val & 0xff;
508 bytes[1] = (val >> 8) & 0xff;
509 bytes[2] = (val >> 16) & 0xff;
510 }
511
512 static __inline void
_lto4l(val,bytes)513 _lto4l(val, bytes)
514 u_int32_t val;
515 u_int8_t *bytes;
516 {
517
518 bytes[0] = val & 0xff;
519 bytes[1] = (val >> 8) & 0xff;
520 bytes[2] = (val >> 16) & 0xff;
521 bytes[3] = (val >> 24) & 0xff;
522 }
523
524 static __inline u_int32_t
_2ltol(bytes)525 _2ltol(bytes)
526 u_int8_t *bytes;
527 {
528 u_int32_t rv;
529
530 rv = bytes[0] | (bytes[1] << 8);
531 return (rv);
532 }
533
534 static __inline u_int32_t
_3ltol(bytes)535 _3ltol(bytes)
536 u_int8_t *bytes;
537 {
538 u_int32_t rv;
539
540 rv = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16);
541 return (rv);
542 }
543
544 static __inline u_int32_t
_4ltol(bytes)545 _4ltol(bytes)
546 u_int8_t *bytes;
547 {
548 u_int32_t rv;
549
550 rv = bytes[0] | (bytes[1] << 8) |
551 (bytes[2] << 16) | (bytes[3] << 24);
552 return (rv);
553 }
554
555 #endif /* SCSI_SCSICONF_H */
556