xref: /openbsd/sys/scsi/scsiconf.h (revision 404b540a)
1 /*	$OpenBSD: scsiconf.h,v 1.102 2009/10/14 01:33:22 dlg 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
52 
53 #include <sys/queue.h>
54 #include <sys/timeout.h>
55 #include <sys/workq.h>
56 #include <sys/mutex.h>
57 #include <machine/cpu.h>
58 #include <scsi/scsi_debug.h>
59 
60 static __inline void _lto2b(u_int32_t val, u_int8_t *bytes);
61 static __inline void _lto3b(u_int32_t val, u_int8_t *bytes);
62 static __inline void _lto4b(u_int32_t val, u_int8_t *bytes);
63 static __inline void _lto8b(u_int64_t val, u_int8_t *bytes);
64 static __inline u_int32_t _2btol(u_int8_t *bytes);
65 static __inline u_int32_t _3btol(u_int8_t *bytes);
66 static __inline u_int32_t _4btol(u_int8_t *bytes);
67 static __inline u_int64_t _5btol(u_int8_t *bytes);
68 static __inline u_int64_t _8btol(u_int8_t *bytes);
69 
70 static __inline void _lto2l(u_int32_t val, u_int8_t *bytes);
71 static __inline void _lto3l(u_int32_t val, u_int8_t *bytes);
72 static __inline void _lto4l(u_int32_t val, u_int8_t *bytes);
73 static __inline u_int32_t _2ltol(u_int8_t *bytes);
74 static __inline u_int32_t _3ltol(u_int8_t *bytes);
75 static __inline u_int32_t _4ltol(u_int8_t *bytes);
76 
77 static __inline void
78 _lto2b(u_int32_t val, u_int8_t *bytes)
79 {
80 
81 	bytes[0] = (val >> 8) & 0xff;
82 	bytes[1] = val & 0xff;
83 }
84 
85 static __inline void
86 _lto3b(u_int32_t val, u_int8_t *bytes)
87 {
88 
89 	bytes[0] = (val >> 16) & 0xff;
90 	bytes[1] = (val >> 8) & 0xff;
91 	bytes[2] = val & 0xff;
92 }
93 
94 static __inline void
95 _lto4b(u_int32_t val, u_int8_t *bytes)
96 {
97 
98 	bytes[0] = (val >> 24) & 0xff;
99 	bytes[1] = (val >> 16) & 0xff;
100 	bytes[2] = (val >> 8) & 0xff;
101 	bytes[3] = val & 0xff;
102 }
103 
104 static __inline void
105 _lto8b(u_int64_t val, u_int8_t *bytes)
106 {
107 
108 	bytes[0] = (val >> 56) & 0xff;
109 	bytes[1] = (val >> 48) & 0xff;
110 	bytes[2] = (val >> 40) & 0xff;
111 	bytes[3] = (val >> 32) & 0xff;
112 	bytes[4] = (val >> 24) & 0xff;
113 	bytes[5] = (val >> 16) & 0xff;
114 	bytes[6] = (val >> 8) & 0xff;
115 	bytes[7] = val & 0xff;
116 }
117 
118 static __inline u_int32_t
119 _2btol(u_int8_t *bytes)
120 {
121 	u_int32_t rv;
122 
123 	rv = (bytes[0] << 8) | bytes[1];
124 	return (rv);
125 }
126 
127 static __inline u_int32_t
128 _3btol(u_int8_t *bytes)
129 {
130 	u_int32_t rv;
131 
132 	rv = (bytes[0] << 16) | (bytes[1] << 8) | bytes[2];
133 	return (rv);
134 }
135 
136 static __inline u_int32_t
137 _4btol(u_int8_t *bytes)
138 {
139 	u_int32_t rv;
140 
141 	rv = (bytes[0] << 24) | (bytes[1] << 16) |
142 	    (bytes[2] << 8) | bytes[3];
143 	return (rv);
144 }
145 
146 static __inline u_int64_t
147 _5btol(u_int8_t *bytes)
148 {
149 	u_int64_t rv;
150 
151 	rv = ((u_int64_t)bytes[0] << 32) |
152 	     ((u_int64_t)bytes[1] << 24) |
153 	     ((u_int64_t)bytes[2] << 16) |
154 	     ((u_int64_t)bytes[3] << 8) |
155 	     (u_int64_t)bytes[4];
156 	return (rv);
157 }
158 
159 static __inline u_int64_t
160 _8btol(u_int8_t *bytes)
161 {
162 	u_int64_t rv;
163 
164 	rv = (((u_int64_t)bytes[0]) << 56) |
165 	    (((u_int64_t)bytes[1]) << 48) |
166 	    (((u_int64_t)bytes[2]) << 40) |
167 	    (((u_int64_t)bytes[3]) << 32) |
168 	    (((u_int64_t)bytes[4]) << 24) |
169 	    (((u_int64_t)bytes[5]) << 16) |
170 	    (((u_int64_t)bytes[6]) << 8) |
171 	    ((u_int64_t)bytes[7]);
172 	return (rv);
173 }
174 
175 static __inline void
176 _lto2l(u_int32_t val, u_int8_t *bytes)
177 {
178 
179 	bytes[0] = val & 0xff;
180 	bytes[1] = (val >> 8) & 0xff;
181 }
182 
183 static __inline void
184 _lto3l(u_int32_t val, u_int8_t *bytes)
185 {
186 
187 	bytes[0] = val & 0xff;
188 	bytes[1] = (val >> 8) & 0xff;
189 	bytes[2] = (val >> 16) & 0xff;
190 }
191 
192 static __inline void
193 _lto4l(u_int32_t val, u_int8_t *bytes)
194 {
195 
196 	bytes[0] = val & 0xff;
197 	bytes[1] = (val >> 8) & 0xff;
198 	bytes[2] = (val >> 16) & 0xff;
199 	bytes[3] = (val >> 24) & 0xff;
200 }
201 
202 static __inline u_int32_t
203 _2ltol(u_int8_t *bytes)
204 {
205 	u_int32_t rv;
206 
207 	rv = bytes[0] | (bytes[1] << 8);
208 	return (rv);
209 }
210 
211 static __inline u_int32_t
212 _3ltol(u_int8_t *bytes)
213 {
214 	u_int32_t rv;
215 
216 	rv = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16);
217 	return (rv);
218 }
219 
220 static __inline u_int32_t
221 _4ltol(u_int8_t *bytes)
222 {
223 	u_int32_t rv;
224 
225 	rv = bytes[0] | (bytes[1] << 8) |
226 	    (bytes[2] << 16) | (bytes[3] << 24);
227 	return (rv);
228 }
229 
230 #ifdef _KERNEL
231 
232 #define DEVID_NONE	0
233 #define DEVID_NAA	1
234 #define DEVID_EUI	2
235 #define DEVID_T10	3
236 
237 struct devid {
238 	u_int8_t	d_type;
239 	u_int8_t	d_flags;
240 #define DEVID_F_PRINT		(1<<0)
241 	u_int8_t	d_refcount;
242 	u_int8_t	d_len;
243 
244 	/*
245 	 * the devid struct is basically a header, the actual id is allocated
246 	 * immediately after it.
247 	 */
248 };
249 
250 #define DEVID_CMP(_a, _b) (					\
251 	(_a) != NULL && (_b) != NULL &&				\
252 	((_a) == (_b) ||					\
253 	((_a)->d_type != DEVID_NONE &&				\
254 	 (_a)->d_type == (_b)->d_type &&			\
255 	 (_a)->d_len == (_b)->d_len &&				\
256 	 bcmp((_a) + 1, (_b) + 1, (_a)->d_len) == 0))		\
257 )
258 
259 struct devid *	devid_alloc(u_int8_t, u_int8_t, u_int8_t, u_int8_t *);
260 struct devid *	devid_copy(struct devid *);
261 void		devid_free(struct devid *);
262 
263 /*
264  * The following documentation tries to describe the relationship between the
265  * various structures defined in this file:
266  *
267  * each adapter type has a scsi_adapter struct. This describes the adapter and
268  *    identifies routines that can be called to use the adapter.
269  * each device type has a scsi_device struct. This describes the device and
270  *    identifies routines that can be called to use the device.
271  * each existing device position (scsibus + target + lun)
272  *    can be described by a scsi_link struct.
273  *    Only scsi positions that actually have devices, have a scsi_link
274  *    structure assigned. so in effect each device has scsi_link struct.
275  *    The scsi_link structure contains information identifying both the
276  *    device driver and the adapter driver for that position on that scsi bus,
277  *    and can be said to 'link' the two.
278  * each individual scsi bus has an array that points to all the scsi_link
279  *    structs associated with that scsi bus. Slots with no device have
280  *    a NULL pointer.
281  * each individual device also knows the address of its own scsi_link
282  *    structure.
283  *
284  *				-------------
285  *
286  * The key to all this is the scsi_link structure which associates all the
287  * other structures with each other in the correct configuration.  The
288  * scsi_link is the connecting information that allows each part of the
289  * scsi system to find the associated other parts.
290  */
291 
292 struct scsi_xfer;
293 struct scsi_link;
294 struct scsibus_softc;
295 
296 /*
297  * Temporary hack
298  */
299 extern int scsi_autoconf;
300 
301 /*
302  * These entrypoints are called by the high-end drivers to get services from
303  * whatever low-end drivers they are attached to.  Each adapter type has one
304  * of these statically allocated.
305  */
306 struct scsi_adapter {
307 	int		(*scsi_cmd)(struct scsi_xfer *);
308 	void		(*scsi_minphys)(struct buf *, struct scsi_link *);
309 	int		(*dev_probe)(struct scsi_link *);
310 	void		(*dev_free)(struct scsi_link *);
311 	int		(*ioctl)(struct scsi_link *, u_long, caddr_t, int,
312 			    struct proc *);
313 };
314 
315 /*
316  * return values for scsi_cmd()
317  */
318 #define SUCCESSFULLY_QUEUED	0
319 #define TRY_AGAIN_LATER		1
320 #define	COMPLETE		2
321 #define	ESCAPE_NOT_SUPPORTED	3
322 #define NO_CCB			4
323 
324 /*
325  * These entry points are called by the low-end drivers to get services from
326  * whatever high-end drivers they are attached to.  Each device type has one
327  * of these statically allocated.
328  */
329 struct scsi_device {
330 	int	(*err_handler)(struct scsi_xfer *);
331 			/* returns -1 to say err processing done */
332 	void	(*start)(void *);
333 
334 	int	(*async)(void);
335 	void	(*done)(struct scsi_xfer *);
336 };
337 
338 /*
339  * This structure describes the connection between an adapter driver and
340  * a device driver, and is used by each to call services provided by
341  * the other, and to allow generic scsi glue code to call these services
342  * as well.
343  */
344 struct scsi_link {
345 	u_int8_t scsibus;		/* the Nth scsibus */
346 	u_int8_t luns;
347 	u_int16_t target;		/* targ of this dev */
348 	u_int16_t lun;			/* lun of this dev */
349 	u_int16_t openings;		/* available operations */
350 	u_int64_t port_wwn;		/* world wide name of port */
351 	u_int64_t node_wwn;		/* world wide name of node */
352 	u_int16_t adapter_target;	/* what are we on the scsi bus */
353 	u_int16_t adapter_buswidth;	/* 8 (regular) or 16 (wide). (0 becomes 8) */
354 	u_int16_t active;		/* operations in progress */
355 	u_int16_t flags;		/* flags that all devices have */
356 #define	SDEV_REMOVABLE	 	0x0001	/* media is removable */
357 #define	SDEV_MEDIA_LOADED 	0x0002	/* device figures are still valid */
358 #define	SDEV_WAITING	 	0x0004	/* a process is waiting for this */
359 #define	SDEV_OPEN	 	0x0008	/* at least 1 open session */
360 #define	SDEV_DBX		0x00f0	/* debugging flags (scsi_debug.h) */
361 #define	SDEV_EJECTING		0x0100	/* eject on device close */
362 #define	SDEV_ATAPI		0x0200	/* device is ATAPI */
363 #define	SDEV_2NDBUS		0x0400	/* device is a 'second' bus device */
364 #define SDEV_UMASS		0x0800	/* device is UMASS SCSI */
365 #define SDEV_VIRTUAL		0x1000	/* device is virtualised on the hba */
366 	u_int16_t quirks;		/* per-device oddities */
367 #define	SDEV_AUTOSAVE		0x0001	/* do implicit SAVEDATAPOINTER on disconnect */
368 #define	SDEV_NOSYNC		0x0002	/* does not grok SDTR */
369 #define	SDEV_NOWIDE		0x0004	/* does not grok WDTR */
370 #define	SDEV_NOTAGS		0x0008	/* lies about having tagged queueing */
371 #define	SDEV_NOSYNCCACHE	0x0100	/* no SYNCHRONIZE_CACHE */
372 #define	ADEV_NOSENSE		0x0200	/* No request sense - ATAPI */
373 #define	ADEV_LITTLETOC		0x0400	/* little-endian TOC - ATAPI */
374 #define	ADEV_NOCAPACITY		0x0800	/* no READ CD CAPACITY */
375 #define	ADEV_NODOORLOCK		0x2000	/* can't lock door */
376 #define SDEV_ONLYBIG		0x4000  /* always use READ_BIG and WRITE_BIG */
377 	struct	scsi_device *device;	/* device entry points etc. */
378 	void	*device_softc;		/* needed for call to foo_start */
379 	struct	scsi_adapter *adapter;	/* adapter entry points etc. */
380 	void	*adapter_softc;		/* needed for call to foo_scsi_cmd */
381 	struct	scsibus_softc *bus;	/* link to the scsibus we're on */
382 	struct	scsi_inquiry_data inqdata; /* copy of INQUIRY data from probe */
383 	struct  devid *id;
384 	struct	mutex mtx;
385 };
386 
387 int	scsiprint(void *, const char *);
388 
389 /*
390  * This describes matching information for scsi_inqmatch().  The more things
391  * match, the higher the configuration priority.
392  */
393 struct scsi_inquiry_pattern {
394 	u_int8_t type;
395 	int removable;
396 	char *vendor;
397 	char *product;
398 	char *revision;
399 };
400 
401 struct scsibus_attach_args {
402 	struct scsi_link *saa_sc_link;
403 };
404 
405 /*
406  * One of these is allocated and filled in for each scsi bus.
407  * It holds pointers to allow the scsi bus to get to the driver
408  * that is running each LUN on the bus.
409  * It also has a template entry which is the prototype struct
410  * supplied by the adapter driver.  This is used to initialise
411  * the others, before they have the rest of the fields filled in.
412  */
413 struct scsibus_softc {
414 	struct device sc_dev;
415 	struct scsi_link *adapter_link;	/* prototype supplied by adapter */
416 	struct scsi_link ***sc_link;
417 	u_int16_t sc_buswidth;
418 };
419 
420 /*
421  * This is used to pass information from the high-level configuration code
422  * to the device-specific drivers.
423  */
424 struct scsi_attach_args {
425 	struct scsi_link *sa_sc_link;
426 	struct scsi_inquiry_data *sa_inqbuf;
427 };
428 
429 /*
430  * Each scsi transaction is fully described by one of these structures.
431  * It includes information about the source of the command and also the
432  * device and adapter for which the command is destined.
433  * (via the scsi_link structure)
434  */
435 struct scsi_xfer {
436 	LIST_ENTRY(scsi_xfer) free_list;
437 	int	flags;
438 	struct	scsi_link *sc_link;	/* all about our device and adapter */
439 	int	retries;		/* the number of times to retry */
440 	int	timeout;		/* in milliseconds */
441 	struct	scsi_generic *cmd;	/* The scsi command to execute */
442 	int	cmdlen;			/* how long it is */
443 	u_char	*data;			/* dma address OR a uio address */
444 	int	datalen;		/* data len (blank if uio)    */
445 	size_t	resid;			/* how much buffer was not touched */
446 	int	error;			/* an error value	*/
447 	struct	buf *bp;		/* If we need to associate with a buf */
448 	struct	scsi_sense_data	sense; /* 32 bytes*/
449 	/*
450 	 * Believe it or not, Some targets fall on the ground with
451 	 * anything but a certain sense length.
452 	 */
453 	int	req_sense_length;	/* Explicit request sense length */
454 	u_int8_t status;		/* SCSI status */
455 	struct	scsi_generic cmdstore;	/* stash the command in here */
456 	/*
457 	 * timeout structure for hba's to use for a command
458 	 */
459 	struct timeout stimeout;
460 	void *cookie;
461 	void (*done)(struct scsi_xfer *);
462 };
463 
464 /*
465  * Per-request Flag values
466  */
467 #define	SCSI_NOSLEEP	0x00001	/* don't sleep */
468 #define	SCSI_POLL	0x00002	/* poll for completion */
469 #define	SCSI_AUTOCONF	0x00003	/* shorthand for SCSI_POLL | SCSI_NOSLEEP */
470 #define	SCSI_USER	0x00004	/* Is a user cmd, call scsi_user_done	*/
471 #define	ITSDONE		0x00008	/* the transfer is as done as it gets	*/
472 #define	SCSI_SILENT	0x00020	/* don't announce NOT READY or MEDIA CHANGE */
473 #define	SCSI_IGNORE_NOT_READY		0x00040	/* ignore NOT READY */
474 #define	SCSI_IGNORE_MEDIA_CHANGE	0x00080	/* ignore MEDIA CHANGE */
475 #define	SCSI_IGNORE_ILLEGAL_REQUEST	0x00100	/* ignore ILLEGAL REQUEST */
476 #define	SCSI_RESET	0x00200	/* Reset the device in question		*/
477 #define	SCSI_DATA_IN	0x00800	/* expect data to come INTO memory	*/
478 #define	SCSI_DATA_OUT	0x01000	/* expect data to flow OUT of memory	*/
479 #define	SCSI_TARGET	0x02000	/* This defines a TARGET mode op.	*/
480 #define	SCSI_ESCAPE	0x04000	/* Escape operation			*/
481 #define SCSI_URGENT	0x08000	/* Urgent operation (e.g., HTAG)	*/
482 #define	SCSI_PRIVATE	0xf0000	/* private to each HBA flags */
483 
484 /*
485  * Escape op-codes.  This provides an extensible setup for operations
486  * that are not scsi commands.  They are intended for modal operations.
487  */
488 
489 #define SCSI_OP_TARGET	0x0001
490 #define	SCSI_OP_RESET	0x0002
491 #define	SCSI_OP_BDINFO	0x0003
492 
493 /*
494  * Error values an adapter driver may return
495  */
496 #define XS_NOERROR	0	/* there is no error, (sense is invalid)  */
497 #define XS_SENSE	1	/* Check the returned sense for the error */
498 #define	XS_DRIVER_STUFFUP 2	/* Driver failed to perform operation	  */
499 #define XS_SELTIMEOUT	3	/* The device timed out.. turned off?	  */
500 #define XS_TIMEOUT	4	/* The Timeout reported was caught by SW  */
501 #define XS_BUSY		5	/* The device busy, try again later?	  */
502 #define XS_SHORTSENSE   6	/* Check the ATAPI sense for the error */
503 #define XS_RESET	8	/* bus was reset; possible retry command  */
504 
505 /*
506  * Possible retries for scsi_test_unit_ready()
507  */
508 #define TEST_READY_RETRIES	5
509 
510 /*
511  * Possible retries for most SCSI commands.
512  */
513 #define SCSI_RETRIES		4
514 
515 const void *scsi_inqmatch(struct scsi_inquiry_data *, const void *, int,
516 	    int, int *);
517 
518 #define scsi_task(_f, _a1, _a2, _fl) \
519     workq_add_task(NULL, (_fl), (_f), (_a1), (_a2))
520 
521 void	scsi_init(void);
522 void	scsi_deinit(void);
523 struct scsi_xfer *
524 	scsi_get_xs(struct scsi_link *, int);
525 void	scsi_free_xs(struct scsi_xfer *, int);
526 int	scsi_execute_xs(struct scsi_xfer *);
527 daddr64_t scsi_size(struct scsi_link *, int, u_int32_t *);
528 int	scsi_test_unit_ready(struct scsi_link *, int, int);
529 int	scsi_inquire(struct scsi_link *, struct scsi_inquiry_data *, int);
530 int	scsi_inquire_vpd(struct scsi_link *, void *, u_int, u_int8_t, int);
531 int	scsi_prevent(struct scsi_link *, int, int);
532 int	scsi_start(struct scsi_link *, int, int);
533 int	scsi_mode_sense(struct scsi_link *, int, int, struct scsi_mode_header *,
534 	    size_t, int, int);
535 int	scsi_mode_sense_big(struct scsi_link *, int, int,
536 	    struct scsi_mode_header_big *, size_t, int, int);
537 void *	scsi_mode_sense_page(struct scsi_mode_header *, int);
538 void *	scsi_mode_sense_big_page(struct scsi_mode_header_big *, int);
539 int	scsi_do_mode_sense(struct scsi_link *, int,
540 	    union scsi_mode_sense_buf *, void **, u_int32_t *, u_int64_t *,
541 	    u_int32_t *, int, int, int *);
542 int	scsi_mode_select(struct scsi_link *, int, struct scsi_mode_header *,
543 	    int, int);
544 int	scsi_mode_select_big(struct scsi_link *, int,
545 	    struct scsi_mode_header_big *, int, int);
546 void	scsi_done(struct scsi_xfer *);
547 void	scsi_user_done(struct scsi_xfer *);
548 int	scsi_scsi_cmd(struct scsi_link *, struct scsi_generic *,
549 	    int cmdlen, u_char *data_addr, int datalen, int retries,
550 	    int timeout, struct buf *bp, int flags);
551 int	scsi_do_ioctl(struct scsi_link *, dev_t, u_long, caddr_t,
552 	    int, struct proc *);
553 void	sc_print_addr(struct scsi_link *);
554 int	scsi_report_luns(struct scsi_link *, int,
555 	    struct scsi_report_luns_data *, u_int32_t, int, int);
556 void	scsi_minphys(struct buf *, struct scsi_link *);
557 
558 void	show_scsi_xs(struct scsi_xfer *);
559 void	scsi_print_sense(struct scsi_xfer *);
560 void	show_mem(u_char *, int);
561 void	scsi_strvis(u_char *, u_char *, int);
562 int	scsi_delay(struct scsi_xfer *, int);
563 
564 int	scsi_probe_bus(struct scsibus_softc *);
565 int	scsi_probe_target(struct scsibus_softc *, int);
566 int	scsi_probe_lun(struct scsibus_softc *, int, int);
567 
568 int	scsi_detach_bus(struct scsibus_softc *, int);
569 int	scsi_detach_target(struct scsibus_softc *, int, int);
570 int	scsi_detach_lun(struct scsibus_softc *, int, int, int);
571 
572 int	scsi_req_probe(struct scsibus_softc *, int, int);
573 int	scsi_req_detach(struct scsibus_softc *, int, int, int);
574 
575 extern const u_int8_t version_to_spc[];
576 #define SCSISPC(x)(version_to_spc[(x) & SID_ANSII])
577 
578 struct scsi_xfer *	scsi_xs_get(struct scsi_link *, int);
579 void			scsi_xs_exec(struct scsi_xfer *);
580 void			scsi_xs_put(struct scsi_xfer *);
581 
582 /*
583  * Entrypoints for multipathing
584  */
585 int	mpath_path_attach(struct scsi_link *);
586 int	mpath_path_detach(struct scsi_link *, int);
587 
588 #endif /* _KERNEL */
589 #endif /* SCSI_SCSICONF_H */
590