1 /* $FreeBSD: releng/5.2/sys/cam/scsi/scsi_low.h 103870 2002-09-23 18:54:32Z alfred $ */
2 /* $NecBSD: scsi_low.h,v 1.24.10.5 2001/06/26 07:31:46 honda Exp $ */
3 /* $NetBSD$ */
4
5 #define SCSI_LOW_DIAGNOSTIC
6 #define SCSI_LOW_ALT_QTAG_ALLOCATE
7
8 /*
9 * [NetBSD for NEC PC-98 series]
10 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
11 * NetBSD/pc98 porting staff. All rights reserved.
12 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
13 * Naofumi HONDA. All rights reserved.
14 *
15 * [Ported for FreeBSD CAM]
16 * Copyright (c) 2000, 2001
17 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * 3. The name of the author may not be used to endorse or promote products
29 * derived from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 #ifndef _SCSI_LOW_H_
45 #define _SCSI_LOW_H_
46
47 /*================================================
48 * Scsi low OSDEP
49 * (All os depend structures should be here!)
50 ================================================*/
51 /******** interface ******************************/
52 #ifdef __NetBSD__
53 #define SCSI_LOW_INTERFACE_XS
54 #endif /* __NetBSD__ */
55
56 #ifdef __FreeBSD__
57 #define SCSI_LOW_INTERFACE_CAM
58 #define CAM
59 #endif /* __FreeBSD__ */
60
61 /******** includes *******************************/
62 #ifdef __NetBSD__
63 #include <i386/Cbus/dev/scsi_dvcfg.h>
64 #include <dev/isa/ccbque.h>
65 #endif /* __NetBSD__ */
66
67 #ifdef __FreeBSD__
68 #include <sys/device_port.h>
69 #include <cam/cam.h>
70 #include <cam/cam_ccb.h>
71 #include <cam/cam_sim.h>
72 #include <cam/cam_xpt_sim.h>
73 #include <cam/cam_debug.h>
74
75 #include <cam/scsi/scsi_dvcfg.h>
76 #include <i386/isa/ccbque.h>
77 #endif /* __FreeBSD__ */
78
79 /******** functions macro ************************/
80 #ifdef __NetBSD__
81 #define SCSI_LOW_DEBUGGER(dev) Debugger()
82 #define SCSI_LOW_DELAY(mu) delay((mu))
83 #define SCSI_LOW_SPLSCSI splbio
84 #define SCSI_LOW_BZERO(pt, size) memset((pt), 0, (size))
85 #endif /* __NetBSD__ */
86
87 #ifdef __FreeBSD__
88 #undef MSG_IDENTIFY
89 #define SCSI_LOW_DEBUGGER(dev) Debugger((dev))
90 #define SCSI_LOW_DELAY(mu) DELAY((mu))
91 #define SCSI_LOW_SPLSCSI splcam
92 #define SCSI_LOW_BZERO(pt, size) bzero((pt), (size))
93 #endif /* __FreeBSD__ */
94
95 /******** os depend interface structures **********/
96 #ifdef __NetBSD__
97 typedef struct scsipi_sense_data scsi_low_osdep_sense_data_t;
98
99 struct scsi_low_osdep_interface {
100 struct device si_dev;
101
102 struct scsipi_link *si_splp;
103 };
104
105 struct scsi_low_osdep_targ_interface {
106 };
107
108 struct scsi_low_osdep_lun_interface {
109 u_int sloi_quirks;
110 };
111 #endif /* __NetBSD__ */
112
113 #ifdef __FreeBSD__
114 typedef struct scsi_sense_data scsi_low_osdep_sense_data_t;
115
116 struct scsi_low_osdep_interface {
117 DEVPORT_DEVICE si_dev;
118
119 struct cam_sim *sim;
120 struct cam_path *path;
121
122 int si_poll_count;
123
124 struct callout_handle engage_ch;
125 struct callout_handle timeout_ch;
126 #ifdef SCSI_LOW_POWFUNC
127 struct callout_handle recover_ch;
128 #endif
129 };
130
131 struct scsi_low_osdep_targ_interface {
132 };
133
134 struct scsi_low_osdep_lun_interface {
135 };
136 #endif /* __FreeBSD__ */
137
138 /******** os depend interface functions *************/
139 struct slccb;
140 struct scsi_low_softc;
141 #define SCSI_LOW_TIMEOUT_STOP 0
142 #define SCSI_LOW_TIMEOUT_START 1
143 #define SCSI_LOW_TIMEOUT_CH_IO 0
144 #define SCSI_LOW_TIMEOUT_CH_ENGAGE 1
145 #define SCSI_LOW_TIMEOUT_CH_RECOVER 2
146
147 struct scsi_low_osdep_funcs {
148 int (*scsi_low_osdep_attach) \
149 (struct scsi_low_softc *);
150 int (*scsi_low_osdep_world_start) \
151 (struct scsi_low_softc *);
152 int (*scsi_low_osdep_dettach) \
153 (struct scsi_low_softc *);
154 int (*scsi_low_osdep_ccb_setup) \
155 (struct scsi_low_softc *, struct slccb *);
156 int (*scsi_low_osdep_done) \
157 (struct scsi_low_softc *, struct slccb *);
158 void (*scsi_low_osdep_timeout) \
159 (struct scsi_low_softc *, int, int);
160 };
161
162 /*================================================
163 * Generic Scsi Low header file
164 * (All os depend structures should be above!)
165 ================================================*/
166 /*************************************************
167 * Scsi low definitions
168 *************************************************/
169 #define SCSI_LOW_SYNC DVF_SCSI_SYNC
170 #define SCSI_LOW_DISC DVF_SCSI_DISC
171 #define SCSI_LOW_WAIT DVF_SCSI_WAIT
172 #define SCSI_LOW_LINK DVF_SCSI_LINK
173 #define SCSI_LOW_QTAG DVF_SCSI_QTAG
174 #define SCSI_LOW_NOPARITY DVF_SCSI_NOPARITY
175 #define SCSI_LOW_SAVESP DVF_SCSI_SAVESP
176 #define SCSI_LOW_DEFCFG DVF_SCSI_DEFCFG
177 #define SCSI_LOW_BITS DVF_SCSI_BITS
178
179 #define SCSI_LOW_PERIOD(n) DVF_SCSI_PERIOD(n)
180 #define SCSI_LOW_OFFSET(n) DVF_SCSI_OFFSET(n)
181
182 /* host scsi id and targets macro */
183 #ifndef SCSI_LOW_NTARGETS
184 #define SCSI_LOW_NTARGETS 8
185 #endif /* SCSI_LOW_NTARGETS */
186 #define SCSI_LOW_NCCB 128
187
188 #define SCSI_LOW_MAX_RETRY 3
189 #define SCSI_LOW_MAX_SELECTION_RETRY 10
190
191 /* timeout control macro */
192 #define SCSI_LOW_TIMEOUT_HZ 10
193 #define SCSI_LOW_MIN_TOUT 12
194 #define SCSI_LOW_TIMEOUT_CHECK_INTERVAL 1
195 #define SCSI_LOW_POWDOWN_TC 15
196 #define SCSI_LOW_MAX_PHCHANGES 256
197 #define SCSI2_RESET_DELAY 5000000
198
199 /* msg */
200 #define SCSI_LOW_MAX_MSGLEN 32
201 #define SCSI_LOW_MSG_LOG_DATALEN 8
202
203 /*************************************************
204 * Scsi Data Pointer
205 *************************************************/
206 /* scsi pointer */
207 struct sc_p {
208 u_int8_t *scp_data;
209 int scp_datalen;
210
211 u_int8_t *scp_cmd;
212 int scp_cmdlen;
213
214 u_int8_t scp_direction;
215 #define SCSI_LOW_RWUNK (-1)
216 #define SCSI_LOW_WRITE 0
217 #define SCSI_LOW_READ 1
218 u_int8_t scp_status;
219 u_int8_t scp_spare[2];
220 };
221
222 /*************************************************
223 * Command Control Block Structure
224 *************************************************/
225 typedef int scsi_low_tag_t;
226 struct targ_info;
227
228 #define SCSI_LOW_UNKLUN ((u_int) -1)
229 #define SCSI_LOW_UNKTAG ((scsi_low_tag_t) -1)
230
231 struct slccb {
232 TAILQ_ENTRY(slccb) ccb_chain;
233
234 void *osdep; /* os depend structure */
235
236 struct targ_info *ti; /* targ_info */
237 struct lun_info *li; /* lun info */
238 struct buf *bp; /* io bufs */
239
240 scsi_low_tag_t ccb_tag; /* effective qtag */
241 scsi_low_tag_t ccb_otag; /* allocated qtag */
242
243 /*****************************************
244 * Scsi data pointers (original and saved)
245 *****************************************/
246 struct sc_p ccb_scp; /* given */
247 struct sc_p ccb_sscp; /* saved scsi data pointer */
248 int ccb_datalen; /* transfered data counter */
249
250 /*****************************************
251 * Msgout
252 *****************************************/
253 u_int ccb_msgoutflag;
254 u_int ccb_omsgoutflag;
255
256 /*****************************************
257 * Error or Timeout counters
258 *****************************************/
259 u_int ccb_flags;
260 #define CCB_INTERNAL 0x0001
261 #define CCB_SENSE 0x0002
262 #define CCB_CLEARQ 0x0004
263 #define CCB_DISCQ 0x0008
264 #define CCB_STARTQ 0x0010
265 #define CCB_POLLED 0x0100 /* polling ccb */
266 #define CCB_NORETRY 0x0200 /* do NOT retry */
267 #define CCB_AUTOSENSE 0x0400 /* do a sence after CA */
268 #define CCB_URGENT 0x0800 /* an urgent ccb */
269 #define CCB_NOSDONE 0x1000 /* do not call an os done routine */
270 #define CCB_SCSIIO 0x2000 /* a normal scsi io coming from upper layer */
271 #define CCB_SILENT 0x4000 /* no terminate messages */
272
273 u_int ccb_error;
274
275 int ccb_rcnt; /* retry counter */
276 int ccb_selrcnt; /* selection retry counter */
277 int ccb_tc; /* timer counter */
278 int ccb_tcmax; /* max timeout */
279
280 /*****************************************
281 * Sense data buffer
282 *****************************************/
283 u_int8_t ccb_scsi_cmd[12];
284 scsi_low_osdep_sense_data_t ccb_sense;
285 };
286
287 /*************************************************
288 * Slccb functions
289 *************************************************/
290 GENERIC_CCB_ASSERT(scsi_low, slccb)
291
292 /*************************************************
293 * Target and Lun structures
294 *************************************************/
295 struct scsi_low_softc;
296 LIST_HEAD(scsi_low_softc_tab, scsi_low_softc);
297 TAILQ_HEAD(targ_info_tab, targ_info);
298 LIST_HEAD(lun_info_tab, lun_info);
299
300 struct lun_info {
301 struct scsi_low_osdep_lun_interface li_sloi;
302
303 int li_lun;
304 struct targ_info *li_ti; /* my target */
305
306 LIST_ENTRY(lun_info) lun_chain; /* targ_info link */
307
308 struct slccbtab li_discq; /* disconnect queue */
309
310 /*
311 * qtag control
312 */
313 int li_maxnexus;
314 int li_maxnqio;
315 int li_nqio;
316 int li_disc;
317
318 #define SCSI_LOW_MAXNEXUS (sizeof(u_int) * NBBY)
319 u_int li_qtagbits;
320
321 #ifdef SCSI_LOW_ALT_QTAG_ALLOCATE
322 u_int8_t li_qtagarray[SCSI_LOW_MAXNEXUS];
323 u_int li_qd;
324 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
325
326 #define SCSI_LOW_QFLAG_CA_QCLEAR 0x01
327 u_int li_qflags;
328
329 /*
330 * lun state
331 */
332 #define SCSI_LOW_LUN_SLEEP 0x00
333 #define SCSI_LOW_LUN_START 0x01
334 #define SCSI_LOW_LUN_INQ 0x02
335 #define SCSI_LOW_LUN_MODEQ 0x03
336 #define SCSI_LOW_LUN_OK 0x04
337 u_int li_state; /* target lun state */
338
339 /*
340 * lun control flags
341 */
342 u_int li_flags_valid; /* valid flags */
343 #define SCSI_LOW_LUN_FLAGS_USER_VALID 0x0001
344 #define SCSI_LOW_LUN_FLAGS_DISK_VALID 0x0002
345 #define SCSI_LOW_LUN_FLAGS_QUIRKS_VALID 0x0004
346 #define SCSI_LOW_LUN_FLAGS_ALL_VALID \
347 (SCSI_LOW_LUN_FLAGS_USER_VALID | \
348 SCSI_LOW_LUN_FLAGS_DISK_VALID | SCSI_LOW_LUN_FLAGS_QUIRKS_VALID)
349
350 u_int li_flags; /* real lun control flags */
351 u_int li_cfgflags; /* lun control flags given by user */
352 u_int li_diskflags; /* lun control flags given by hardware info */
353 u_int li_quirks; /* lun control flags given by upper layer */
354
355 /* inq buffer */
356 struct scsi_low_inq_data {
357 u_int8_t sd_type;
358 u_int8_t sd_sp1;
359 u_int8_t sd_version;
360 u_int8_t sd_resp;
361 u_int8_t sd_len;
362 u_int8_t sd_sp2[2];
363 u_int8_t sd_support;
364 } __packed li_inq;
365
366 /* modeq buffer */
367 struct scsi_low_mode_sense_data {
368 u_int8_t sms_header[4];
369 struct {
370 u_int8_t cmp_page;
371 u_int8_t cmp_length;
372 u_int8_t cmp_rlec;
373 u_int8_t cmp_qc;
374 u_int8_t cmp_eca;
375 u_int8_t cmp_spare[3];
376 } __packed sms_cmp;
377
378 } li_sms;
379 };
380
381 struct scsi_low_msg_log {
382 int slml_ptr;
383 struct {
384 u_int8_t msg[2];
385 } slml_msg[SCSI_LOW_MSG_LOG_DATALEN];
386 };
387
388 struct targ_info {
389 struct scsi_low_osdep_targ_interface ti_slti;
390
391 TAILQ_ENTRY(targ_info) ti_chain; /* targ_info link */
392
393 struct scsi_low_softc *ti_sc; /* our softc */
394 u_int ti_id; /* scsi id */
395
396 /*
397 * Lun chain
398 */
399 struct lun_info_tab ti_litab; /* lun chain */
400
401 /*
402 * total disconnected nexus
403 */
404 int ti_disc;
405
406 /*
407 * Scsi phase control
408 */
409
410 #define PH_NULL 0x00
411 #define PH_ARBSTART 0x01
412 #define PH_SELSTART 0x02
413 #define PH_SELECTED 0x03
414 #define PH_CMD 0x04
415 #define PH_DATA 0x05
416 #define PH_MSGIN 0x06
417 #define PH_MSGOUT 0x07
418 #define PH_STAT 0x08
419 #define PH_DISC 0x09
420 #define PH_RESEL 0x0a
421 u_int ti_phase; /* scsi phase */
422 u_int ti_ophase; /* old scsi phase */
423
424 /*
425 * Msg in
426 */
427 u_int ti_msginptr; /* msgin ptr */
428 u_int ti_msginlen; /* expected msg length */
429 int ti_msgin_parity_error; /* parity error detected */
430 u_int8_t ti_msgin[SCSI_LOW_MAX_MSGLEN]; /* msgin buffer */
431
432 /*
433 * Msg out
434 */
435 u_int ti_msgflags; /* msgs to be asserted */
436 u_int ti_omsgflags; /* msgs asserted */
437 u_int ti_emsgflags; /* a msg currently asserted */
438 #define SCSI_LOW_MSG_RESET 0x00000001
439 #define SCSI_LOW_MSG_REJECT 0x00000002
440 #define SCSI_LOW_MSG_PARITY 0x00000004
441 #define SCSI_LOW_MSG_ERROR 0x00000008
442 #define SCSI_LOW_MSG_IDENTIFY 0x00000010
443 #define SCSI_LOW_MSG_ABORT 0x00000020
444 #define SCSI_LOW_MSG_TERMIO 0x00000040
445 #define SCSI_LOW_MSG_SIMPLE_QTAG 0x00000080
446 #define SCSI_LOW_MSG_ORDERED_QTAG 0x00000100
447 #define SCSI_LOW_MSG_HEAD_QTAG 0x00000200
448 #define SCSI_LOW_MSG_ABORT_QTAG 0x00000400
449 #define SCSI_LOW_MSG_CLEAR_QTAG 0x00000800
450 #define SCSI_LOW_MSG_WIDE 0x00001000
451 #define SCSI_LOW_MSG_SYNCH 0x00002000
452 #define SCSI_LOW_MSG_NOOP 0x00004000
453 #define SCSI_LOW_MSG_LAST 0x00008000
454 #define SCSI_LOW_MSG_ALL 0xffffffff
455
456 /* msgout buffer */
457 u_int8_t ti_msgoutstr[SCSI_LOW_MAX_MSGLEN]; /* scsi msgout */
458 u_int ti_msgoutlen; /* msgout strlen */
459
460 /*
461 * target initialize msgout
462 */
463 u_int ti_setup_msg; /* setup msgout requests */
464 u_int ti_setup_msg_done;
465
466 /*
467 * synch and wide data info
468 */
469 u_int ti_flags_valid; /* valid flags */
470 #define SCSI_LOW_TARG_FLAGS_USER_VALID 0x0001
471 #define SCSI_LOW_TARG_FLAGS_DISK_VALID 0x0002
472 #define SCSI_LOW_TARG_FLAGS_QUIRKS_VALID 0x0004
473 #define SCSI_LOW_TARG_FLAGS_ALL_VALID \
474 (SCSI_LOW_TARG_FLAGS_USER_VALID | \
475 SCSI_LOW_TARG_FLAGS_DISK_VALID | SCSI_LOW_TARG_FLAGS_QUIRKS_VALID)
476
477 u_int ti_diskflags; /* given target disk flags */
478 u_int ti_quirks; /* given target quirk */
479
480 struct synch {
481 u_int8_t offset;
482 u_int8_t period;
483 } ti_osynch, ti_maxsynch; /* synch data */
484
485 #define SCSI_LOW_BUS_WIDTH_8 0
486 #define SCSI_LOW_BUS_WIDTH_16 1
487 #define SCSI_LOW_BUS_WIDTH_32 2
488 u_int ti_owidth, ti_width;
489
490 /*
491 * lun info size.
492 */
493 int ti_lunsize;
494
495 #ifdef SCSI_LOW_DIAGNOSTIC
496 struct scsi_low_msg_log ti_log_msgout;
497 struct scsi_low_msg_log ti_log_msgin;
498 #endif /* SCSI_LOW_DIAGNOSTIC */
499 };
500
501 /*************************************************
502 * COMMON HEADER STRUCTURE
503 *************************************************/
504 struct scsi_low_softc;
505 struct proc;
506 typedef struct scsi_low_softc *sc_low_t;
507
508 #define SCSI_LOW_START_OK 0
509 #define SCSI_LOW_START_FAIL 1
510 #define SCSI_LOW_INFO_ALLOC 0
511 #define SCSI_LOW_INFO_REVOKE 1
512 #define SCSI_LOW_INFO_DEALLOC 2
513 #define SCSI_LOW_POWDOWN 1
514 #define SCSI_LOW_ENGAGE 2
515
516 #define SC_LOW_INIT_T (int (*)(sc_low_t, int))
517 #define SC_LOW_BUSRST_T (void (*)(sc_low_t))
518 #define SC_LOW_TARG_INIT_T (int (*)(sc_low_t, struct targ_info *, int))
519 #define SC_LOW_LUN_INIT_T (int (*)(sc_low_t, struct targ_info *, struct lun_info *, int))
520 #define SC_LOW_SELECT_T (int (*)(sc_low_t, struct slccb *))
521 #define SC_LOW_ATTEN_T (void (*)(sc_low_t))
522 #define SC_LOW_NEXUS_T (int (*)(sc_low_t))
523 #define SC_LOW_MSG_T (int (*)(sc_low_t, struct targ_info *, u_int))
524 #define SC_LOW_POLL_T (int (*)(void *))
525 #define SC_LOW_POWER_T (int (*)(sc_low_t, u_int))
526 #define SC_LOW_TIMEOUT_T (int (*)(sc_low_t))
527
528 struct scsi_low_funcs {
529 int (*scsi_low_init)(sc_low_t, int);
530 void (*scsi_low_bus_reset)(sc_low_t);
531 int (*scsi_low_targ_init)(sc_low_t, struct targ_info *, int);
532 int (*scsi_low_lun_init)(sc_low_t, struct targ_info *, struct lun_info *, int);
533 int (*scsi_low_start_bus)(sc_low_t, struct slccb *);
534 int (*scsi_low_establish_lun_nexus)(sc_low_t);
535 int (*scsi_low_establish_ccb_nexus)(sc_low_t);
536 void (*scsi_low_attention)(sc_low_t);
537 int (*scsi_low_msg)(sc_low_t, struct targ_info *, u_int);
538 int (*scsi_low_timeout)(sc_low_t);
539 int (*scsi_low_poll)(void *);
540 int (*scsi_low_power)(sc_low_t, u_int);
541 int (*scsi_low_ioctl)(sc_low_t, u_long, caddr_t, int, struct proc *);
542 };
543
544 struct scsi_low_softc {
545 /* os depend structure */
546 struct scsi_low_osdep_interface sl_si;
547 #define sl_dev sl_si.si_dev
548 struct scsi_low_osdep_funcs *sl_osdep_fp;
549 u_char sl_xname[16];
550
551 /* our chain */
552 LIST_ENTRY(scsi_low_softc) sl_chain;
553
554 /* my targets */
555 struct targ_info *sl_ti[SCSI_LOW_NTARGETS];
556 struct targ_info_tab sl_titab;
557
558 /* current active T_L_Q nexus */
559 struct targ_info *sl_Tnexus; /* Target nexus */
560 struct lun_info *sl_Lnexus; /* Lun nexus */
561 struct slccb *sl_Qnexus; /* Qtag nexus */
562 int sl_nexus_call;
563
564 /* ccb start queue */
565 struct slccbtab sl_start;
566
567 /* retry limit and phase change counter */
568 int sl_max_retry;
569 int sl_ph_count;
570 int sl_timeout_count;
571
572 /* selection & total num disconnect targets */
573 int sl_nio;
574 int sl_disc;
575 int sl_retry_sel;
576 struct slccb *sl_selid;
577
578 /* attention */
579 int sl_atten; /* ATN asserted */
580 int sl_clear_atten; /* negate ATN required */
581
582 /* scsi phase suggested by scsi msg */
583 u_int sl_msgphase;
584 #define MSGPH_NULL 0x00 /* no msg */
585 #define MSGPH_DISC 0x01 /* disconnect msg */
586 #define MSGPH_CMDC 0x02 /* cmd complete msg */
587 #define MSGPH_ABORT 0x03 /* abort seq */
588 #define MSGPH_TERM 0x04 /* current io terminate */
589 #define MSGPH_LCTERM 0x05 /* cmd link terminated */
590 #define MSGPH_RESET 0x06 /* reset target */
591
592 /* error */
593 u_int sl_error; /* error flags */
594 #define FATALIO 0x0001 /* generic io error & retry io */
595 #define ABORTIO 0x0002 /* generic io error & terminate io */
596 #define TIMEOUTIO 0x0004 /* watch dog timeout */
597 #define SELTIMEOUTIO 0x0008 /* selection timeout */
598 #define PDMAERR 0x0010 /* dma xfer error */
599 #define MSGERR 0x0020 /* msgsys error */
600 #define PARITYERR 0x0040 /* parity error */
601 #define BUSYERR 0x0080 /* target busy error */
602 #define STATERR 0x0100 /* status error */
603 #define UACAERR 0x0200 /* target CA state, no sense check */
604 #define SENSEIO 0x1000 /* cmd not excuted but sense data ok */
605 #define SENSEERR 0x2000 /* cmd not excuted and sense data bad */
606 #define UBFERR 0x4000 /* unexpected bus free */
607 #define PENDINGIO 0x8000 /* ccb start not yet */
608 #define SCSI_LOW_ERRORBITS "\020\017ubferr\016senseerr\015senseio\012uacaerr\011staterr\010busy\007parity\006msgerr\005pdmaerr\004seltimeout\003timeout\002abort\001fatal"
609
610 /* current scsi data pointer */
611 struct sc_p sl_scp;
612
613 /* power control */
614 u_int sl_active; /* host is busy state */
615 int sl_powc; /* power down timer counter */
616 u_int sl_rstep; /* resume step */
617
618 /* configuration flags */
619 u_int sl_flags;
620 #define HW_POWDOWN 0x0001
621 #define HW_RESUME 0x0002
622 #define HW_PDMASTART 0x0004
623 #define HW_INACTIVE 0x0008
624 #define HW_POWERCTRL 0x0010
625 #define HW_INITIALIZING 0x0020
626 #define HW_READ_PADDING 0x1000
627 #define HW_WRITE_PADDING 0x2000
628
629 u_int sl_cfgflags;
630 #define CFG_NODISC 0x0001
631 #define CFG_NOPARITY 0x0002
632 #define CFG_NOATTEN 0x0004
633 #define CFG_ASYNC 0x0008
634 #define CFG_NOQTAG 0x0010
635
636 int sl_show_result;
637 #define SHOW_SYNCH_NEG 0x0001
638 #define SHOW_WIDE_NEG 0x0002
639 #define SHOW_CALCF_RES 0x0010
640 #define SHOW_PROBE_RES 0x0020
641 #define SHOW_ALL_NEG -1
642
643 /* host informations */
644 u_int sl_hostid;
645 int sl_nluns;
646 int sl_ntargs;
647 int sl_openings;
648
649 /* interface functions */
650 struct scsi_low_funcs *sl_funcs;
651
652 /* targinfo size */
653 int sl_targsize;
654
655 #if defined(i386) || defined(__i386__)
656 u_int sl_irq; /* XXX */
657 #endif /* i386 */
658 };
659
660 /*************************************************
661 * SCSI LOW service functions
662 *************************************************/
663 /*
664 * Scsi low attachment function.
665 */
666 int scsi_low_attach(struct scsi_low_softc *, int, int, int, int, int);
667 int scsi_low_dettach(struct scsi_low_softc *);
668
669 /*
670 * Scsi low interface activate or deactivate functions
671 */
672 int scsi_low_is_busy(struct scsi_low_softc *);
673 int scsi_low_activate(struct scsi_low_softc *);
674 int scsi_low_deactivate(struct scsi_low_softc *);
675
676 /*
677 * Scsi phase "bus service" functions.
678 * These functions are corresponding to each scsi bus phaeses.
679 */
680 /* bus idle phase (other initiators or targets release bus) */
681 void scsi_low_bus_idle(struct scsi_low_softc *);
682
683 /* arbitration and selection phase */
684 void scsi_low_arbit_fail(struct scsi_low_softc *, struct slccb *);
685 static __inline void scsi_low_arbit_win(struct scsi_low_softc *);
686
687 /* msgout phase */
688 #define SCSI_LOW_MSGOUT_INIT 0x00000001
689 #define SCSI_LOW_MSGOUT_UNIFY 0x00000002
690 int scsi_low_msgout(struct scsi_low_softc *, struct targ_info *, u_int);
691
692 /* msgin phase */
693 #define SCSI_LOW_DATA_PE 0x80000000
694 int scsi_low_msgin(struct scsi_low_softc *, struct targ_info *, u_int);
695
696 /* statusin phase */
697 static __inline int scsi_low_statusin(struct scsi_low_softc *, struct targ_info *, u_int);
698
699 /* data phase */
700 int scsi_low_data(struct scsi_low_softc *, struct targ_info *, struct buf **, int);
701 static __inline void scsi_low_data_finish(struct scsi_low_softc *);
702
703 /* cmd phase */
704 int scsi_low_cmd(struct scsi_low_softc *, struct targ_info *);
705
706 /* reselection phase */
707 struct targ_info *scsi_low_reselected(struct scsi_low_softc *, u_int);
708
709 /* disconnection phase */
710 int scsi_low_disconnected(struct scsi_low_softc *, struct targ_info *);
711
712 /*
713 * Scsi bus restart function.
714 * Canncel all established nexuses => scsi system initialized => restart jobs.
715 */
716 #define SCSI_LOW_RESTART_HARD 1
717 #define SCSI_LOW_RESTART_SOFT 0
718 int scsi_low_restart(struct scsi_low_softc *, int, u_char *);
719
720 /*
721 * Scsi utility fucntions
722 */
723 /* print current status */
724 void scsi_low_print(struct scsi_low_softc *, struct targ_info *);
725
726 /* bus reset utility */
727 void scsi_low_bus_reset(struct scsi_low_softc *);
728
729 /*************************************************
730 * Message macro defs
731 *************************************************/
732 #define SCSI_LOW_SETUP_PHASE(ti, phase) \
733 { \
734 (ti)->ti_ophase = ti->ti_phase; \
735 (ti)->ti_phase = (phase); \
736 }
737
738 #define SCSI_LOW_SETUP_MSGPHASE(slp, PHASE) \
739 { \
740 (slp)->sl_msgphase = (PHASE); \
741 }
742
743 #define SCSI_LOW_ASSERT_ATN(slp) \
744 { \
745 (slp)->sl_atten = 1; \
746 }
747
748 #define SCSI_LOW_DEASSERT_ATN(slp) \
749 { \
750 (slp)->sl_atten = 0; \
751 }
752
753 /*************************************************
754 * Inline functions
755 *************************************************/
756 static __inline void scsi_low_attention(struct scsi_low_softc *);
757 static __inline int scsi_low_is_msgout_continue(struct targ_info *, u_int);
758 static __inline int scsi_low_assert_msg(struct scsi_low_softc *, struct targ_info *, u_int, int);
759 static __inline int scsi_low_is_disconnect_ok(struct slccb *);
760
761 static __inline int
762 scsi_low_is_msgout_continue(ti, mask)
763 struct targ_info *ti;
764 u_int mask;
765 {
766
767 return ((ti->ti_msgflags & (~mask)) != 0);
768 }
769
770 static __inline int
771 scsi_low_is_disconnect_ok(cb)
772 struct slccb *cb;
773 {
774
775 return ((cb->li->li_flags & SCSI_LOW_DISC) != 0 &&
776 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) == 0);
777 }
778
779 static __inline void
780 scsi_low_attention(slp)
781 struct scsi_low_softc *slp;
782 {
783
784 if (slp->sl_atten != 0)
785 return;
786
787 (*slp->sl_funcs->scsi_low_attention) (slp);
788 SCSI_LOW_ASSERT_ATN(slp);
789 }
790
791 static __inline int
792 scsi_low_assert_msg(slp, ti, msg, now)
793 struct scsi_low_softc *slp;
794 struct targ_info *ti;
795 u_int msg;
796 int now;
797 {
798
799 ti->ti_msgflags |= msg;
800 if (now != 0)
801 scsi_low_attention(slp);
802 return 0;
803 }
804
805 static __inline void
806 scsi_low_arbit_win(slp)
807 struct scsi_low_softc *slp;
808 {
809
810 slp->sl_selid = NULL;
811 }
812
813 static __inline void
814 scsi_low_data_finish(slp)
815 struct scsi_low_softc *slp;
816 {
817
818 if (slp->sl_Qnexus != NULL)
819 {
820 slp->sl_Qnexus->ccb_datalen = slp->sl_scp.scp_datalen;
821 }
822 }
823
824 static __inline int
825 scsi_low_statusin(slp, ti, c)
826 struct scsi_low_softc *slp;
827 struct targ_info *ti;
828 u_int c;
829 {
830
831 slp->sl_ph_count ++;
832 if ((c & SCSI_LOW_DATA_PE) != 0)
833 {
834 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 0);
835 return EIO;
836 }
837 slp->sl_scp.scp_status = (u_int8_t) c;
838 return 0;
839 }
840
841 /*************************************************
842 * Message out defs
843 *************************************************/
844 /* XXX: use scsi_message.h */
845 #define ST_GOOD 0x00
846 #define ST_CHKCOND 0x02
847 #define ST_MET 0x04
848 #define ST_BUSY 0x08
849 #define ST_INTERGOOD 0x10
850 #define ST_INTERMET 0x14
851 #define ST_CONFLICT 0x18
852 #define ST_CMDTERM 0x22
853 #define ST_QUEFULL 0x28
854 #define ST_UNKNOWN 0xff
855
856 #define MSG_COMP 0x00
857 #define MSG_EXTEND 0x01
858
859 #define MKMSG_EXTEND(XLEN, XCODE) ((((u_int)(XLEN)) << NBBY) | ((u_int)(XCODE)))
860 #define MSG_EXTEND_MDPCODE 0x00
861 #define MSG_EXTEND_MDPLEN 0x05
862 #define MSG_EXTEND_SYNCHCODE 0x01
863 #define MSG_EXTEND_SYNCHLEN 0x03
864 #define MSG_EXTEND_WIDECODE 0x03
865 #define MSG_EXTEND_WIDELEN 0x02
866
867 #define MSG_SAVESP 0x02
868 #define MSG_RESTORESP 0x03
869 #define MSG_DISCON 0x04
870 #define MSG_I_ERROR 0x05
871 #define MSG_ABORT 0x06
872 #define MSG_REJECT 0x07
873 #define MSG_NOOP 0x08
874 #define MSG_PARITY 0x09
875 #define MSG_LCOMP 0x0a
876 #define MSG_LCOMP_F 0x0b
877 #define MSG_RESET 0x0c
878 #define MSG_ABORT_QTAG 0x0d
879 #define MSG_CLEAR_QTAG 0x0e
880 #define MSG_TERM_IO 0x11
881 #define MSG_SIMPLE_QTAG 0x20
882 #define MSG_HEAD_QTAG 0x21
883 #define MSG_ORDERED_QTAG 0x22
884 #define MSG_IDENTIFY 0x80
885 #define MSG_IDENTIFY_DISCPRIV 0x40
886 #endif /* !_SCSI_LOW_H_ */
Cache object: d6e23fa46e90bed5cc86da5a03d1d746
|