2 * Copyright (c) 1999 Luoqi Chen.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/dev/aic/aic.c,v 1.8 2000/01/14 23:42:35 imp Exp $
27 * $DragonFly: src/sys/dev/disk/aic/aic.c,v 1.12 2008/01/05 07:27:09 pavalos Exp $
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
34 #include <sys/thread2.h>
36 #include <bus/cam/cam.h>
37 #include <bus/cam/cam_ccb.h>
38 #include <bus/cam/cam_sim.h>
39 #include <bus/cam/cam_xpt_sim.h>
40 #include <bus/cam/cam_debug.h>
42 #include <bus/cam/scsi/scsi_message.h>
44 #include "aic6360reg.h"
47 static void aic_action (struct cam_sim
*sim
, union ccb
*ccb
);
48 static void aic_execute_scb (void *arg
, bus_dma_segment_t
*dm_segs
,
50 static void aic_start (struct aic_softc
*aic
);
51 static void aic_select (struct aic_softc
*aic
);
52 static void aic_selected (struct aic_softc
*aic
);
53 static void aic_reselected (struct aic_softc
*aic
);
54 static void aic_reconnect (struct aic_softc
*aic
, int tag
);
55 static void aic_cmd (struct aic_softc
*aic
);
56 static void aic_msgin (struct aic_softc
*aic
);
57 static void aic_handle_msgin (struct aic_softc
*aic
);
58 static void aic_msgout (struct aic_softc
*aic
);
59 static void aic_datain (struct aic_softc
*aic
);
60 static void aic_dataout (struct aic_softc
*aic
);
61 static void aic_done (struct aic_softc
*aic
, struct aic_scb
*scb
);
62 static void aic_poll (struct cam_sim
*sim
);
63 static void aic_timeout (void *arg
);
64 static void aic_scsi_reset (struct aic_softc
*aic
);
65 static void aic_chip_reset (struct aic_softc
*aic
);
66 static void aic_reset (struct aic_softc
*aic
, int initiate_reset
);
68 devclass_t aic_devclass
;
70 static struct aic_scb
*free_scbs
;
72 static struct aic_scb
*
73 aic_get_scb(struct aic_softc
*aic
)
79 if ((scb
= free_scbs
) != NULL
)
80 free_scbs
= (struct aic_scb
*)free_scbs
->ccb
;
87 aic_free_scb(struct aic_softc
*aic
, struct aic_scb
*scb
)
91 if ((aic
->flags
& AIC_RESOURCE_SHORTAGE
) != 0 &&
92 (scb
->ccb
->ccb_h
.status
& CAM_RELEASE_SIMQ
) == 0) {
93 scb
->ccb
->ccb_h
.status
|= CAM_RELEASE_SIMQ
;
94 aic
->flags
&= ~AIC_RESOURCE_SHORTAGE
;
97 scb
->ccb
= (union ccb
*)free_scbs
;
104 aic_action(struct cam_sim
*sim
, union ccb
*ccb
)
106 struct aic_softc
*aic
;
108 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
, ("aic_action\n"));
110 aic
= (struct aic_softc
*)cam_sim_softc(sim
);
112 switch (ccb
->ccb_h
.func_code
) {
113 case XPT_SCSI_IO
: /* Execute the requested I/O operation */
114 case XPT_RESET_DEV
: /* Bus Device Reset the specified SCSI device */
118 if ((scb
= aic_get_scb(aic
)) == NULL
) {
120 aic
->flags
|= AIC_RESOURCE_SHORTAGE
;
122 xpt_freeze_simq(aic
->sim
, /*count*/1);
123 ccb
->ccb_h
.status
= CAM_REQUEUE_REQ
;
129 ccb
->ccb_h
.ccb_scb_ptr
= scb
;
130 ccb
->ccb_h
.ccb_aic_ptr
= aic
;
132 scb
->target
= ccb
->ccb_h
.target_id
;
133 scb
->lun
= ccb
->ccb_h
.target_lun
;
135 if (ccb
->ccb_h
.func_code
== XPT_SCSI_IO
) {
136 scb
->cmd_len
= ccb
->csio
.cdb_len
;
137 if (ccb
->ccb_h
.flags
& CAM_CDB_POINTER
) {
138 if (ccb
->ccb_h
.flags
& CAM_CDB_PHYS
) {
139 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
140 aic_free_scb(aic
, scb
);
144 scb
->cmd_ptr
= ccb
->csio
.cdb_io
.cdb_ptr
;
146 scb
->cmd_ptr
= ccb
->csio
.cdb_io
.cdb_bytes
;
148 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
149 if ((ccb
->ccb_h
.flags
& CAM_SCATTER_VALID
) ||
150 (ccb
->ccb_h
.flags
& CAM_DATA_PHYS
)) {
151 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
152 aic_free_scb(aic
, scb
);
156 scb
->data_ptr
= ccb
->csio
.data_ptr
;
157 scb
->data_len
= ccb
->csio
.dxfer_len
;
159 scb
->data_ptr
= NULL
;
162 aic_execute_scb(scb
, NULL
, 0, 0);
164 scb
->flags
|= SCB_DEVICE_RESET
;
165 aic_execute_scb(scb
, NULL
, 0, 0);
169 case XPT_SET_TRAN_SETTINGS
:
171 struct ccb_trans_settings
*cts
= cts
= &ccb
->cts
;
172 struct aic_tinfo
*ti
= &aic
->tinfo
[ccb
->ccb_h
.target_id
];
173 #ifdef CAM_NEW_TRAN_CODE
174 struct ccb_trans_settings_scsi
*scsi
=
175 &cts
->proto_specific
.scsi
;
176 struct ccb_trans_settings_spi
*spi
=
177 &cts
->xport_specific
.spi
;
181 if ((spi
->valid
& CTS_SPI_VALID_DISC
) != 0 &&
182 (aic
->flags
& AIC_DISC_ENABLE
) != 0) {
183 if ((spi
->flags
& CTS_SPI_FLAGS_DISC_ENB
) != 0)
184 ti
->flags
|= TINFO_DISC_ENB
;
186 ti
->flags
&= ~TINFO_DISC_ENB
;
189 if ((scsi
->valid
& CTS_SCSI_VALID_TQ
) != 0) {
190 if ((scsi
->flags
& CTS_SCSI_FLAGS_TAG_ENB
) != 0)
191 ti
->flags
|= TINFO_TAG_ENB
;
193 ti
->flags
&= ~TINFO_TAG_ENB
;
196 if ((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) != 0) {
197 ti
->goal
.period
= spi
->sync_period
;
199 if (ti
->goal
.period
> aic
->min_period
) {
202 } else if (ti
->goal
.period
< aic
->max_period
)
203 ti
->goal
.period
= aic
->max_period
;
206 if ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) != 0) {
207 ti
->goal
.offset
= spi
->sync_offset
;
208 if (ti
->goal
.offset
== 0)
210 else if (ti
->goal
.offset
> AIC_SYNC_OFFSET
)
211 ti
->goal
.offset
= AIC_SYNC_OFFSET
;
214 if ((ti
->goal
.period
!= ti
->current
.period
)
215 || (ti
->goal
.offset
!= ti
->current
.offset
))
216 ti
->flags
|= TINFO_SDTR_NEGO
;
221 if ((cts
->valid
& CCB_TRANS_DISC_VALID
) != 0 &&
222 (aic
->flags
& AIC_DISC_ENABLE
) != 0) {
223 if ((cts
->flags
& CCB_TRANS_DISC_ENB
) != 0)
224 ti
->flags
|= TINFO_DISC_ENB
;
226 ti
->flags
&= ~TINFO_DISC_ENB
;
229 if ((cts
->valid
& CCB_TRANS_TQ_VALID
) != 0) {
230 if ((cts
->flags
& CCB_TRANS_TAG_ENB
) != 0)
231 ti
->flags
|= TINFO_TAG_ENB
;
233 ti
->flags
&= ~TINFO_TAG_ENB
;
236 if ((cts
->valid
& CCB_TRANS_SYNC_RATE_VALID
) != 0) {
237 ti
->goal
.period
= cts
->sync_period
;
238 if (ti
->goal
.period
!= ti
->current
.period
)
239 ti
->flags
|= TINFO_SDTR_NEGO
;
242 if ((cts
->valid
& CCB_TRANS_SYNC_OFFSET_VALID
) != 0) {
243 ti
->goal
.offset
= cts
->sync_offset
;
244 if (ti
->goal
.offset
!= ti
->current
.offset
)
245 ti
->flags
|= TINFO_SDTR_NEGO
;
250 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
254 case XPT_GET_TRAN_SETTINGS
:
256 struct ccb_trans_settings
*cts
= &ccb
->cts
;
257 struct aic_tinfo
*ti
= &aic
->tinfo
[ccb
->ccb_h
.target_id
];
258 #ifdef CAM_NEW_TRAN_CODE
259 struct ccb_trans_settings_scsi
*scsi
=
260 &cts
->proto_specific
.scsi
;
261 struct ccb_trans_settings_spi
*spi
=
262 &cts
->xport_specific
.spi
;
264 cts
->protocol
= PROTO_SCSI
;
265 cts
->protocol_version
= SCSI_REV_2
;
266 cts
->transport
= XPORT_SPI
;
267 cts
->transport_version
= 2;
268 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
269 spi
->flags
&= ~CTS_SPI_FLAGS_DISC_ENB
;
272 if ((ti
->flags
& TINFO_DISC_ENB
) != 0)
273 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
274 if ((ti
->flags
& TINFO_TAG_ENB
) != 0)
275 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
277 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
) {
278 spi
->sync_period
= ti
->current
.period
;
279 spi
->sync_offset
= ti
->current
.offset
;
281 spi
->sync_period
= ti
->user
.period
;
282 spi
->sync_offset
= ti
->user
.offset
;
286 spi
->bus_width
= MSG_EXT_WDTR_BUS_8_BIT
;
287 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
288 | CTS_SPI_VALID_SYNC_OFFSET
289 | CTS_SPI_VALID_BUS_WIDTH
290 | CTS_SPI_VALID_DISC
;
291 scsi
->valid
= CTS_SCSI_VALID_TQ
;
294 cts
->flags
&= ~(CCB_TRANS_DISC_ENB
|CCB_TRANS_TAG_ENB
);
295 if ((ti
->flags
& TINFO_DISC_ENB
) != 0)
296 cts
->flags
|= CCB_TRANS_DISC_ENB
;
297 if ((ti
->flags
& TINFO_TAG_ENB
) != 0)
298 cts
->flags
|= CCB_TRANS_TAG_ENB
;
300 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) != 0) {
301 cts
->sync_period
= ti
->current
.period
;
302 cts
->sync_offset
= ti
->current
.offset
;
304 cts
->sync_period
= ti
->user
.period
;
305 cts
->sync_offset
= ti
->user
.offset
;
307 cts
->bus_width
= MSG_EXT_WDTR_BUS_8_BIT
;
311 cts
->valid
= CCB_TRANS_SYNC_RATE_VALID
312 | CCB_TRANS_SYNC_OFFSET_VALID
313 | CCB_TRANS_BUS_WIDTH_VALID
314 | CCB_TRANS_DISC_VALID
315 | CCB_TRANS_TQ_VALID
;
318 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
322 case XPT_CALC_GEOMETRY
:
324 cam_calc_geometry(&ccb
->ccg
, /*extended*/1);
328 case XPT_RESET_BUS
: /* Reset the specified SCSI bus */
329 aic_reset(aic
, /*initiate_reset*/TRUE
);
330 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
333 case XPT_PATH_INQ
: /* Path routing inquiry */
335 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
337 cpi
->version_num
= 1; /* XXX??? */
338 cpi
->hba_inquiry
= PI_SDTR_ABLE
| PI_TAG_ABLE
;
339 cpi
->target_sprt
= 0;
341 cpi
->hba_eng_cnt
= 0;
344 cpi
->initiator_id
= aic
->initiator
;
345 cpi
->bus_id
= cam_sim_bus(sim
);
346 cpi
->base_transfer_speed
= 3300;
347 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
348 strncpy(cpi
->hba_vid
, "Adaptec", HBA_IDLEN
);
349 strncpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
350 cpi
->unit_number
= cam_sim_unit(sim
);
351 #ifdef CAM_NEW_TRAN_CODE
352 cpi
->transport
= XPORT_SPI
;
353 cpi
->transport_version
= 2;
354 cpi
->protocol
= PROTO_SCSI
;
355 cpi
->protocol_version
= SCSI_REV_2
;
357 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
362 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
369 aic_execute_scb(void *arg
, bus_dma_segment_t
*dm_segs
, int nseg
, int error
)
371 struct aic_scb
*scb
= (struct aic_scb
*)arg
;
372 union ccb
*ccb
= scb
->ccb
;
373 struct aic_softc
*aic
= (struct aic_softc
*)ccb
->ccb_h
.ccb_aic_ptr
;
377 if (ccb
->ccb_h
.status
!= CAM_REQ_INPROG
) {
379 aic_free_scb(aic
, scb
);
384 scb
->flags
|= SCB_ACTIVE
;
385 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
386 TAILQ_INSERT_TAIL(&aic
->pending_ccbs
, &ccb
->ccb_h
, sim_links
.tqe
);
388 callout_reset(&ccb
->ccb_h
.timeout_ch
, (ccb
->ccb_h
.timeout
* hz
) / 1000,
396 * Start another command if the controller is not busy.
399 aic_start(struct aic_softc
*aic
)
401 struct ccb_hdr
*ccb_h
;
402 struct aic_tinfo
*ti
;
404 if (aic
->state
!= AIC_IDLE
)
407 TAILQ_FOREACH(ccb_h
, &aic
->pending_ccbs
, sim_links
.tqe
) {
408 ti
= &aic
->tinfo
[ccb_h
->target_id
];
409 if ((ti
->lubusy
& (1 << ccb_h
->target_lun
)) == 0) {
410 TAILQ_REMOVE(&aic
->pending_ccbs
, ccb_h
, sim_links
.tqe
);
411 aic
->nexus
= (struct aic_scb
*)ccb_h
->ccb_scb_ptr
;
417 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_start: idle\n"));
419 aic_outb(aic
, SIMODE0
, ENSELDI
);
420 aic_outb(aic
, SIMODE1
, ENSCSIRST
);
421 aic_outb(aic
, SCSISEQ
, ENRESELI
);
428 aic_select(struct aic_softc
*aic
)
430 struct aic_scb
*scb
= aic
->nexus
;
432 CAM_DEBUG(scb
->ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
433 ("aic_select - ccb %p\n", scb
->ccb
));
435 aic
->state
= AIC_SELECTING
;
437 aic_outb(aic
, DMACNTRL1
, 0);
438 aic_outb(aic
, SCSIID
, aic
->initiator
<< OID_S
| scb
->target
);
439 aic_outb(aic
, SXFRCTL1
, STIMO_256ms
| ENSTIMER
|
440 (aic
->flags
& AIC_PARITY_ENABLE
? ENSPCHK
: 0));
442 aic_outb(aic
, SIMODE0
, ENSELDI
|ENSELDO
);
443 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENSELTIMO
);
444 aic_outb(aic
, SCSISEQ
, ENRESELI
|ENSELO
|ENAUTOATNO
);
448 * We have successfully selected a target, prepare for the information
452 aic_selected(struct aic_softc
*aic
)
454 struct aic_scb
*scb
= aic
->nexus
;
455 union ccb
*ccb
= scb
->ccb
;
456 struct aic_tinfo
*ti
= &aic
->tinfo
[scb
->target
];
458 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
459 ("aic_selected - ccb %p\n", ccb
));
461 aic
->state
= AIC_HASNEXUS
;
463 if (scb
->flags
& SCB_DEVICE_RESET
) {
464 aic
->msg_buf
[0] = MSG_BUS_DEV_RESET
;
466 aic
->msg_outq
= AIC_MSG_MSGBUF
;
468 aic
->msg_outq
= AIC_MSG_IDENTIFY
;
469 if ((ti
->flags
& TINFO_TAG_ENB
) != 0 &&
470 (ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
) != 0)
471 aic
->msg_outq
|= AIC_MSG_TAG_Q
;
473 ti
->lubusy
|= 1 << scb
->lun
;
474 if ((ti
->flags
& TINFO_SDTR_NEGO
) != 0)
475 aic
->msg_outq
|= AIC_MSG_SDTR
;
478 aic_outb(aic
, CLRSINT0
, CLRSELDO
);
479 aic_outb(aic
, CLRSINT1
, CLRBUSFREE
);
480 aic_outb(aic
, SCSISEQ
, ENAUTOATNP
);
481 aic_outb(aic
, SIMODE0
, 0);
482 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENBUSFREE
|ENREQINIT
);
483 aic_outb(aic
, SCSIRATE
, ti
->scsirate
);
487 * We are re-selected by a target, save the target id and wait for the
488 * target to further identify itself.
491 aic_reselected(struct aic_softc
*aic
)
495 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_reselected\n"));
498 * If we have started a selection, it must have lost out in
499 * the arbitration, put the command back to the pending queue.
502 TAILQ_INSERT_HEAD(&aic
->pending_ccbs
,
503 &aic
->nexus
->ccb
->ccb_h
, sim_links
.tqe
);
507 selid
= aic_inb(aic
, SELID
) & ~(1 << aic
->initiator
);
508 if (selid
& (selid
- 1)) {
509 /* this should never have happened */
510 kprintf("aic_reselected: invalid selid %x\n", selid
);
511 aic_reset(aic
, /*initiate_reset*/TRUE
);
515 aic
->state
= AIC_RESELECTED
;
516 aic
->target
= ffs(selid
) - 1;
519 aic_outb(aic
, CLRSINT0
, CLRSELDI
);
520 aic_outb(aic
, CLRSINT1
, CLRBUSFREE
);
521 aic_outb(aic
, SIMODE0
, 0);
522 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENBUSFREE
|ENREQINIT
);
523 aic_outb(aic
, SCSISEQ
, ENAUTOATNP
);
524 aic_outb(aic
, SCSIRATE
, aic
->tinfo
[aic
->target
].scsirate
);
528 * Raise ATNO to signal the target that we have a message for it.
531 aic_sched_msgout(struct aic_softc
*aic
, u_int8_t msg
)
534 aic
->msg_buf
[0] = msg
;
537 aic
->msg_outq
|= AIC_MSG_MSGBUF
;
538 aic_outb(aic
, SCSISIGO
, aic_inb(aic
, SCSISIGI
) | ATNO
);
542 * Wait for SPIORDY (SCSI PIO ready) flag, or a phase change.
545 aic_spiordy(struct aic_softc
*aic
)
547 while (!(aic_inb(aic
, DMASTAT
) & INTSTAT
) &&
548 !(aic_inb(aic
, SSTAT0
) & SPIORDY
))
550 return !(aic_inb(aic
, DMASTAT
) & INTSTAT
);
554 * Reestablish a disconnected nexus.
557 aic_reconnect(struct aic_softc
*aic
, int tag
)
560 struct ccb_hdr
*ccb_h
;
562 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_reconnect\n"));
566 TAILQ_FOREACH(ccb_h
, &aic
->nexus_ccbs
, sim_links
.tqe
) {
567 scb
= (struct aic_scb
*)ccb_h
->ccb_scb_ptr
;
568 if (scb
->target
== aic
->target
&& scb
->lun
== aic
->lun
&&
569 (tag
== -1 || scb
->tag
== tag
))
573 /* ABORT if nothing is found */
576 aic_sched_msgout(aic
, MSG_ABORT
);
578 aic_sched_msgout(aic
, MSG_ABORT_TAG
);
579 xpt_async(AC_UNSOL_RESEL
, aic
->path
, NULL
);
583 /* Reestablish the nexus */
584 TAILQ_REMOVE(&aic
->nexus_ccbs
, ccb_h
, sim_links
.tqe
);
586 scb
->flags
&= ~SCB_DISCONNECTED
;
587 aic
->state
= AIC_HASNEXUS
;
594 aic_msgin(struct aic_softc
*aic
)
598 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_msgin\n"));
600 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENPHASEMIS
|ENBUSFREE
);
601 aic_outb(aic
, SXFRCTL0
, CHEN
|SPIOEN
);
603 aic
->flags
&= ~AIC_DROP_MSGIN
;
607 * If a parity error is detected, drop the remaining
608 * bytes and inform the target so it could resend
611 if (aic_inb(aic
, SSTAT1
) & SCSIPERR
) {
612 aic_outb(aic
, CLRSINT1
, CLRSCSIPERR
);
613 aic
->flags
|= AIC_DROP_MSGIN
;
614 aic_sched_msgout(aic
, MSG_PARITY_ERROR
);
616 if ((aic
->flags
& AIC_DROP_MSGIN
)) {
617 aic_inb(aic
, SCSIDAT
);
620 /* read the message byte without ACKing on it */
621 aic
->msg_buf
[aic
->msg_len
++] = aic_inb(aic
, SCSIBUS
);
622 if (aic
->msg_buf
[0] == MSG_EXTENDED
) {
623 if (aic
->msg_len
< 2) {
624 (void) aic_inb(aic
, SCSIDAT
);
627 switch (aic
->msg_buf
[2]) {
629 msglen
= MSG_EXT_SDTR_LEN
;
632 msglen
= MSG_EXT_WDTR_LEN
;
638 if (aic
->msg_buf
[1] != msglen
) {
639 aic
->flags
|= AIC_DROP_MSGIN
;
640 aic_sched_msgout(aic
, MSG_MESSAGE_REJECT
);
643 } else if (aic
->msg_buf
[0] >= 0x20 && aic
->msg_buf
[0] <= 0x2f)
648 * If we have a complete message, handle it before the final
649 * ACK (in case we decide to reject the message).
651 if (aic
->msg_len
== msglen
) {
652 aic_handle_msgin(aic
);
655 /* ACK on the message byte */
656 (void) aic_inb(aic
, SCSIDAT
);
657 } while (aic_spiordy(aic
));
659 aic_outb(aic
, SXFRCTL0
, CHEN
);
660 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENBUSFREE
|ENREQINIT
);
667 aic_handle_msgin(struct aic_softc
*aic
)
670 struct ccb_hdr
*ccb_h
;
671 struct aic_tinfo
*ti
;
672 struct ccb_trans_settings neg
;
673 #ifdef CAM_NEW_TRAN_CODE
674 struct ccb_trans_settings_spi
*spi
= &neg
.xport_specific
.spi
;
677 if (aic
->state
== AIC_RESELECTED
) {
678 if (!MSG_ISIDENTIFY(aic
->msg_buf
[0])) {
679 aic_sched_msgout(aic
, MSG_MESSAGE_REJECT
);
682 aic
->lun
= aic
->msg_buf
[0] & MSG_IDENTIFY_LUNMASK
;
683 if (aic
->tinfo
[aic
->target
].lubusy
& (1 << aic
->lun
))
684 aic_reconnect(aic
, -1);
686 aic
->state
= AIC_RECONNECTING
;
690 if (aic
->state
== AIC_RECONNECTING
) {
691 if (aic
->msg_buf
[0] != MSG_SIMPLE_Q_TAG
) {
692 aic_sched_msgout(aic
, MSG_MESSAGE_REJECT
);
695 aic_reconnect(aic
, aic
->msg_buf
[1]);
699 switch (aic
->msg_buf
[0]) {
700 case MSG_CMDCOMPLETE
: {
701 struct ccb_scsiio
*csio
;
703 ccb_h
= &scb
->ccb
->ccb_h
;
704 csio
= &scb
->ccb
->csio
;
705 if ((scb
->flags
& SCB_SENSE
) != 0) {
706 /* auto REQUEST SENSE command */
707 scb
->flags
&= ~SCB_SENSE
;
708 csio
->sense_resid
= scb
->data_len
;
709 if (scb
->status
== SCSI_STATUS_OK
) {
711 CAM_SCSI_STATUS_ERROR
|CAM_AUTOSNS_VALID
;
712 /*scsi_sense_print(csio);*/
714 ccb_h
->status
|= CAM_AUTOSENSE_FAIL
;
715 kprintf("ccb %p sense failed %x\n",
719 csio
->scsi_status
= scb
->status
;
720 csio
->resid
= scb
->data_len
;
721 if (scb
->status
== SCSI_STATUS_OK
) {
722 /* everything goes well */
723 ccb_h
->status
|= CAM_REQ_CMP
;
724 } else if ((ccb_h
->flags
& CAM_DIS_AUTOSENSE
) == 0 &&
725 (csio
->scsi_status
== SCSI_STATUS_CHECK_COND
||
726 csio
->scsi_status
== SCSI_STATUS_CMD_TERMINATED
)) {
727 /* try to retrieve sense information */
728 scb
->flags
|= SCB_SENSE
;
729 aic
->flags
|= AIC_BUSFREE_OK
;
732 ccb_h
->status
|= CAM_SCSI_STATUS_ERROR
;
735 aic
->flags
|= AIC_BUSFREE_OK
;
739 switch (aic
->msg_buf
[2]) {
742 ti
= &aic
->tinfo
[scb
->target
];
743 if (ti
->flags
& TINFO_SDTR_SENT
) {
744 ti
->current
.period
= aic
->msg_buf
[3];
745 ti
->current
.offset
= aic
->msg_buf
[4];
747 ti
->current
.period
= aic
->msg_buf
[3] =
748 max(ti
->goal
.period
, aic
->msg_buf
[3]);
749 ti
->current
.offset
= aic
->msg_buf
[4] =
750 min(ti
->goal
.offset
, aic
->msg_buf
[4]);
752 * The target initiated the negotiation,
753 * send back a response.
755 aic_sched_msgout(aic
, 0);
757 ti
->flags
&= ~(TINFO_SDTR_SENT
|TINFO_SDTR_NEGO
);
758 ti
->scsirate
= ti
->current
.offset
? ti
->current
.offset
|
759 ((ti
->current
.period
* 4 + 49) / 50 - 2) << 4 : 0;
760 aic_outb(aic
, SCSIRATE
, ti
->scsirate
);
761 memset(&neg
, 0, sizeof (neg
));
762 #ifdef CAM_NEW_TRAN_CODE
763 neg
.protocol
= PROTO_SCSI
;
764 neg
.protocol_version
= SCSI_REV_2
;
765 neg
.transport
= XPORT_SPI
;
766 neg
.transport_version
= 2;
767 spi
->sync_period
= ti
->goal
.period
= ti
->current
.period
;
768 spi
->sync_offset
= ti
->goal
.offset
= ti
->current
.offset
;
769 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
770 | CTS_SPI_VALID_SYNC_OFFSET
;
772 neg
.sync_period
= ti
->goal
.period
= ti
->current
.period
;
773 neg
.sync_offset
= ti
->goal
.offset
= ti
->current
.offset
;
774 neg
.valid
= CCB_TRANS_SYNC_RATE_VALID
775 | CCB_TRANS_SYNC_OFFSET_VALID
;
777 ccb_h
= &scb
->ccb
->ccb_h
;
778 xpt_setup_ccb(&neg
.ccb_h
, ccb_h
->path
, 1);
779 xpt_async(AC_TRANSFER_NEG
, ccb_h
->path
, &neg
);
783 aic_sched_msgout(aic
, MSG_MESSAGE_REJECT
);
789 ccb_h
= &scb
->ccb
->ccb_h
;
790 TAILQ_INSERT_TAIL(&aic
->nexus_ccbs
, ccb_h
, sim_links
.tqe
);
791 scb
->flags
|= SCB_DISCONNECTED
;
792 aic
->flags
|= AIC_BUSFREE_OK
;
794 CAM_DEBUG(ccb_h
->path
, CAM_DEBUG_TRACE
, ("disconnected\n"));
796 case MSG_MESSAGE_REJECT
:
797 switch (aic
->msg_outq
& -aic
->msg_outq
) {
800 ti
= &aic
->tinfo
[scb
->target
];
801 ti
->flags
&= ~TINFO_TAG_ENB
;
802 ti
->lubusy
|= 1 << scb
->lun
;
806 ti
= &aic
->tinfo
[scb
->target
];
807 ti
->current
.period
= ti
->goal
.period
= 0;
808 ti
->current
.offset
= ti
->goal
.offset
= 0;
809 ti
->flags
&= ~(TINFO_SDTR_SENT
|TINFO_SDTR_NEGO
);
811 aic_outb(aic
, SCSIRATE
, ti
->scsirate
);
812 memset(&neg
, 0, sizeof (neg
));
813 #ifdef CAM_NEW_TRAN_CODE
814 neg
.protocol
= PROTO_SCSI
;
815 neg
.protocol_version
= SCSI_REV_2
;
816 neg
.transport
= XPORT_SPI
;
817 neg
.transport_version
= 2;
818 spi
->sync_period
= ti
->current
.period
;
819 spi
->sync_offset
= ti
->current
.offset
;
820 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
821 | CTS_SPI_VALID_SYNC_OFFSET
;
823 neg
.sync_period
= ti
->current
.period
;
824 neg
.sync_offset
= ti
->current
.offset
;
825 neg
.valid
= CCB_TRANS_SYNC_RATE_VALID
826 | CCB_TRANS_SYNC_OFFSET_VALID
;
828 ccb_h
= &scb
->ccb
->ccb_h
;
829 xpt_setup_ccb(&neg
.ccb_h
, ccb_h
->path
, 1);
830 xpt_async(AC_TRANSFER_NEG
, ccb_h
->path
, &neg
);
836 case MSG_SAVEDATAPOINTER
:
838 case MSG_RESTOREPOINTERS
:
843 aic_sched_msgout(aic
, MSG_MESSAGE_REJECT
);
852 aic_msgout(struct aic_softc
*aic
)
856 struct aic_tinfo
*ti
;
859 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_msgout\n"));
861 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENPHASEMIS
|ENBUSFREE
);
862 aic_outb(aic
, SXFRCTL0
, CHEN
|SPIOEN
);
865 * If the previous phase is also the message out phase,
866 * we need to retransmit all the messages, probably
867 * because the target has detected a parity error during
868 * the past transmission.
870 if (aic
->prev_phase
== PH_MSGOUT
)
871 aic
->msg_outq
= aic
->msg_sent
;
874 int q
= aic
->msg_outq
;
875 if (msgidx
> 0 && msgidx
== aic
->msg_len
) {
876 /* complete message sent, start the next one */
884 /* setup the message */
886 case AIC_MSG_IDENTIFY
:
889 ti
= &aic
->tinfo
[scb
->target
];
890 aic
->msg_buf
[0] = MSG_IDENTIFY(scb
->lun
,
891 (ti
->flags
& TINFO_DISC_ENB
) &&
892 !(ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
));
898 aic
->msg_buf
[0] = ccb
->csio
.tag_action
;
899 aic
->msg_buf
[1] = scb
->tag
;
904 ti
= &aic
->tinfo
[scb
->target
];
905 aic
->msg_buf
[0] = MSG_EXTENDED
;
906 aic
->msg_buf
[1] = MSG_EXT_SDTR_LEN
;
907 aic
->msg_buf
[2] = MSG_EXT_SDTR
;
908 aic
->msg_buf
[3] = ti
->goal
.period
;
909 aic
->msg_buf
[4] = ti
->goal
.offset
;
910 aic
->msg_len
= MSG_EXT_SDTR_LEN
+ 2;
911 ti
->flags
|= TINFO_SDTR_SENT
;
914 /* a single message already in the buffer */
915 if (aic
->msg_buf
[0] == MSG_BUS_DEV_RESET
||
916 aic
->msg_buf
[0] == MSG_ABORT
||
917 aic
->msg_buf
[0] == MSG_ABORT_TAG
)
918 aic
->flags
|= AIC_BUSFREE_OK
;
923 * If this is the last message byte of all messages,
924 * clear ATNO to signal transmission complete.
926 if ((q
& (q
- 1)) == 0 && msgidx
== aic
->msg_len
- 1)
927 aic_outb(aic
, CLRSINT1
, CLRATNO
);
928 /* transmit the message byte */
929 aic_outb(aic
, SCSIDAT
, aic
->msg_buf
[msgidx
++]);
930 } while (aic_spiordy(aic
));
932 aic_outb(aic
, SXFRCTL0
, CHEN
);
933 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENBUSFREE
|ENREQINIT
);
940 aic_datain(struct aic_softc
*aic
)
942 struct aic_scb
*scb
= aic
->nexus
;
943 u_int8_t dmastat
, dmacntrl0
;
946 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_datain\n"));
948 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENPHASEMIS
|ENBUSFREE
);
949 aic_outb(aic
, SXFRCTL0
, SCSIEN
|DMAEN
|CHEN
);
952 if (aic
->flags
& AIC_DWIO_ENABLE
)
953 dmacntrl0
|= DWORDPIO
;
954 aic_outb(aic
, DMACNTRL0
, dmacntrl0
);
956 while (scb
->data_len
> 0) {
958 /* wait for the fifo to fill up or a phase change */
959 dmastat
= aic_inb(aic
, DMASTAT
);
960 if (dmastat
& (INTSTAT
|DFIFOFULL
))
963 if (dmastat
& DFIFOFULL
) {
967 * No more data, wait for the remaining bytes in
968 * the scsi fifo to be transfer to the host fifo.
970 while (!(aic_inb(aic
, SSTAT2
) & SEMPTY
))
972 n
= aic_inb(aic
, FIFOSTAT
);
974 n
= imin(scb
->data_len
, n
);
975 if (aic
->flags
& AIC_DWIO_ENABLE
) {
977 aic_insl(aic
, DMADATALONG
, scb
->data_ptr
, n
>>2);
978 scb
->data_ptr
+= n
& ~3;
979 scb
->data_len
-= n
& ~3;
984 aic_insw(aic
, DMADATA
, scb
->data_ptr
, n
>> 1);
985 scb
->data_ptr
+= n
& ~1;
986 scb
->data_len
-= n
& ~1;
991 aic_outb(aic
, DMACNTRL0
, ENDMA
|B8MODE
);
992 aic_insb(aic
, DMADATA
, scb
->data_ptr
, n
);
995 aic_outb(aic
, DMACNTRL0
, dmacntrl0
);
998 if (dmastat
& INTSTAT
)
1002 aic_outb(aic
, SXFRCTL0
, CHEN
);
1003 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENBUSFREE
|ENREQINIT
);
1010 aic_dataout(struct aic_softc
*aic
)
1012 struct aic_scb
*scb
= aic
->nexus
;
1013 u_int8_t dmastat
, dmacntrl0
, sstat2
;
1016 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_dataout\n"));
1018 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENPHASEMIS
|ENBUSFREE
);
1019 aic_outb(aic
, SXFRCTL0
, SCSIEN
|DMAEN
|CHEN
);
1021 dmacntrl0
= ENDMA
|WRITE
;
1022 if (aic
->flags
& AIC_DWIO_ENABLE
)
1023 dmacntrl0
|= DWORDPIO
;
1024 aic_outb(aic
, DMACNTRL0
, dmacntrl0
);
1026 while (scb
->data_len
> 0) {
1028 /* wait for the fifo to clear up or a phase change */
1029 dmastat
= aic_inb(aic
, DMASTAT
);
1030 if (dmastat
& (INTSTAT
|DFIFOEMP
))
1033 if (dmastat
& INTSTAT
)
1035 n
= imin(scb
->data_len
, FIFOSIZE
);
1036 if (aic
->flags
& AIC_DWIO_ENABLE
) {
1038 aic_outsl(aic
, DMADATALONG
, scb
->data_ptr
,n
>>2);
1039 scb
->data_ptr
+= n
& ~3;
1040 scb
->data_len
-= n
& ~3;
1045 aic_outsw(aic
, DMADATA
, scb
->data_ptr
, n
>> 1);
1046 scb
->data_ptr
+= n
& ~1;
1047 scb
->data_len
-= n
& ~1;
1052 aic_outb(aic
, DMACNTRL0
, ENDMA
|WRITE
|B8MODE
);
1053 aic_outsb(aic
, DMADATA
, scb
->data_ptr
, n
);
1056 aic_outb(aic
, DMACNTRL0
, dmacntrl0
);
1061 /* wait until all bytes in the fifos are transmitted */
1062 dmastat
= aic_inb(aic
, DMASTAT
);
1063 sstat2
= aic_inb(aic
, SSTAT2
);
1064 if ((dmastat
& DFIFOEMP
) && (sstat2
& SEMPTY
))
1066 if (dmastat
& INTSTAT
) {
1067 /* adjust for untransmitted bytes */
1068 n
= aic_inb(aic
, FIFOSTAT
) + (sstat2
& 0xf);
1071 /* clear the fifo */
1072 aic_outb(aic
, SXFRCTL0
, CHEN
|CLRCH
);
1073 aic_outb(aic
, DMACNTRL0
, RSTFIFO
);
1078 aic_outb(aic
, SXFRCTL0
, CHEN
);
1079 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENBUSFREE
|ENREQINIT
);
1083 * Send the scsi command.
1086 aic_cmd(struct aic_softc
*aic
)
1088 struct aic_scb
*scb
= aic
->nexus
;
1089 struct scsi_request_sense sense_cmd
;
1091 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_cmd\n"));
1093 if (scb
->flags
& SCB_SENSE
) {
1094 /* autosense request */
1095 sense_cmd
.opcode
= REQUEST_SENSE
;
1096 sense_cmd
.byte2
= scb
->lun
<< 5;
1097 sense_cmd
.length
= scb
->ccb
->csio
.sense_len
;
1098 sense_cmd
.control
= 0;
1099 sense_cmd
.unused
[0] = 0;
1100 sense_cmd
.unused
[1] = 0;
1101 scb
->cmd_ptr
= (u_int8_t
*)&sense_cmd
;
1102 scb
->cmd_len
= sizeof(sense_cmd
);
1103 scb
->data_ptr
= (u_int8_t
*)&scb
->ccb
->csio
.sense_data
;
1104 scb
->data_len
= scb
->ccb
->csio
.sense_len
;
1107 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENPHASEMIS
|ENBUSFREE
);
1108 aic_outb(aic
, DMACNTRL0
, ENDMA
|WRITE
);
1109 aic_outb(aic
, SXFRCTL0
, SCSIEN
|DMAEN
|CHEN
);
1110 aic_outsw(aic
, DMADATA
, (u_int16_t
*)scb
->cmd_ptr
, scb
->cmd_len
>> 1);
1111 while ((aic_inb(aic
, SSTAT2
) & SEMPTY
) == 0 &&
1112 (aic_inb(aic
, DMASTAT
) & INTSTAT
) == 0)
1114 aic_outb(aic
, SXFRCTL0
, CHEN
);
1115 aic_outb(aic
, SIMODE1
, ENSCSIRST
|ENBUSFREE
|ENREQINIT
);
1119 * Finish off a command. The caller is responsible to remove the ccb
1123 aic_done(struct aic_softc
*aic
, struct aic_scb
*scb
)
1125 union ccb
*ccb
= scb
->ccb
;
1127 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
1128 ("aic_done - ccb %p status %x resid %d\n",
1129 ccb
, ccb
->ccb_h
.status
, ccb
->csio
.resid
));
1131 callout_stop(&ccb
->ccb_h
.timeout_ch
);
1133 if ((scb
->flags
& SCB_DEVICE_RESET
) != 0 &&
1134 ccb
->ccb_h
.func_code
!= XPT_RESET_DEV
) {
1135 struct cam_path
*path
;
1136 struct ccb_hdr
*ccb_h
;
1139 error
= xpt_create_path(&path
, /*periph*/NULL
,
1140 cam_sim_path(aic
->sim
),
1144 if (error
== CAM_REQ_CMP
) {
1145 xpt_async(AC_SENT_BDR
, path
, NULL
);
1146 xpt_free_path(path
);
1149 ccb_h
= TAILQ_FIRST(&aic
->pending_ccbs
);
1150 while (ccb_h
!= NULL
) {
1151 struct aic_scb
*pending_scb
;
1153 pending_scb
= (struct aic_scb
*)ccb_h
->ccb_scb_ptr
;
1154 if (ccb_h
->target_id
== scb
->target
) {
1155 ccb_h
->status
|= CAM_BDR_SENT
;
1156 ccb_h
= TAILQ_NEXT(ccb_h
, sim_links
.tqe
);
1157 TAILQ_REMOVE(&aic
->pending_ccbs
,
1158 &pending_scb
->ccb
->ccb_h
, sim_links
.tqe
);
1159 aic_done(aic
, pending_scb
);
1161 callout_reset(&ccb_h
->timeout_ch
,
1162 (ccb_h
->timeout
* hz
) / 1000,
1163 aic_timeout
, pending_scb
);
1164 ccb_h
= TAILQ_NEXT(ccb_h
, sim_links
.tqe
);
1168 ccb_h
= TAILQ_FIRST(&aic
->nexus_ccbs
);
1169 while (ccb_h
!= NULL
) {
1170 struct aic_scb
*nexus_scb
;
1172 nexus_scb
= (struct aic_scb
*)ccb_h
->ccb_scb_ptr
;
1173 if (ccb_h
->target_id
== scb
->target
) {
1174 ccb_h
->status
|= CAM_BDR_SENT
;
1175 ccb_h
= TAILQ_NEXT(ccb_h
, sim_links
.tqe
);
1176 TAILQ_REMOVE(&aic
->nexus_ccbs
,
1177 &nexus_scb
->ccb
->ccb_h
, sim_links
.tqe
);
1178 aic_done(aic
, nexus_scb
);
1180 callout_reset(&ccb_h
->timeout_ch
,
1181 (ccb_h
->timeout
* hz
) / 1000,
1182 aic_timeout
, nexus_scb
);
1183 ccb_h
= TAILQ_NEXT(ccb_h
, sim_links
.tqe
);
1188 if (aic
->nexus
== scb
|| scb
->flags
& SCB_DISCONNECTED
)
1189 aic
->tinfo
[scb
->target
].lubusy
&= ~(1 << scb
->lun
);
1191 if (aic
->nexus
== scb
) {
1194 aic_free_scb(aic
, scb
);
1199 aic_poll(struct cam_sim
*sim
)
1201 aic_intr(cam_sim_softc(sim
));
1205 aic_timeout(void *arg
)
1207 struct aic_scb
*scb
= (struct aic_scb
*)arg
;
1208 union ccb
*ccb
= scb
->ccb
;
1209 struct aic_softc
*aic
= (struct aic_softc
*)ccb
->ccb_h
.ccb_aic_ptr
;
1211 xpt_print_path(ccb
->ccb_h
.path
);
1212 kprintf("ccb %p - timed out", ccb
);
1213 if (aic
->nexus
&& aic
->nexus
!= scb
)
1214 kprintf(", nexus %p", aic
->nexus
->ccb
);
1215 kprintf(", phase 0x%x, state %d\n", aic_inb(aic
, SCSISIGI
), aic
->state
);
1219 if ((scb
->flags
& SCB_ACTIVE
) == 0) {
1221 xpt_print_path(ccb
->ccb_h
.path
);
1222 kprintf("ccb %p - timed out already completed\n", ccb
);
1226 if ((scb
->flags
& SCB_DEVICE_RESET
) == 0 && aic
->nexus
== scb
) {
1227 struct ccb_hdr
*ccb_h
= &scb
->ccb
->ccb_h
;
1229 if ((ccb_h
->status
& CAM_RELEASE_SIMQ
) == 0) {
1230 xpt_freeze_simq(aic
->sim
, /*count*/1);
1231 ccb_h
->status
|= CAM_RELEASE_SIMQ
;
1234 TAILQ_FOREACH(ccb_h
, &aic
->pending_ccbs
, sim_links
.tqe
)
1235 callout_stop(&ccb_h
->timeout_ch
);
1237 TAILQ_FOREACH(ccb_h
, &aic
->nexus_ccbs
, sim_links
.tqe
)
1238 callout_stop(&ccb_h
->timeout_ch
);
1240 scb
->flags
|= SCB_DEVICE_RESET
;
1241 callout_reset(&ccb
->ccb_h
.timeout_ch
, 5 * hz
, aic_timeout
, scb
);
1242 aic_sched_msgout(aic
, MSG_BUS_DEV_RESET
);
1244 if (aic
->nexus
== scb
) {
1245 ccb
->ccb_h
.status
|= CAM_CMD_TIMEOUT
;
1248 aic_reset(aic
, /*initiate_reset*/TRUE
);
1257 struct aic_softc
*aic
= (struct aic_softc
*)arg
;
1258 u_int8_t sstat0
, sstat1
;
1260 struct aic_scb
*scb
;
1262 if (!(aic_inb(aic
, DMASTAT
) & INTSTAT
))
1265 aic_outb(aic
, DMACNTRL0
, 0);
1267 sstat0
= aic_inb(aic
, SSTAT0
);
1268 sstat1
= aic_inb(aic
, SSTAT1
);
1270 if ((sstat1
& SCSIRSTI
) != 0) {
1271 /* a device-initiated bus reset */
1272 aic_outb(aic
, CLRSINT1
, CLRSCSIRSTI
);
1273 aic_reset(aic
, /*initiate_reset*/FALSE
);
1277 if ((sstat1
& SCSIPERR
) != 0) {
1278 aic_outb(aic
, CLRSINT1
, CLRSCSIPERR
);
1279 aic_sched_msgout(aic
, MSG_PARITY_ERROR
);
1280 aic_outb(aic
, DMACNTRL0
, INTEN
);
1284 if (aic_inb(aic
, SSTAT4
)) {
1285 aic_outb(aic
, CLRSERR
, CLRSYNCERR
|CLRFWERR
|CLRFRERR
);
1286 aic_reset(aic
, /*initiate_reset*/TRUE
);
1290 if (aic
->state
<= AIC_SELECTING
) {
1291 if ((sstat0
& SELDI
) != 0) {
1292 aic_reselected(aic
);
1293 aic_outb(aic
, DMACNTRL0
, INTEN
);
1297 if ((sstat0
& SELDO
) != 0) {
1299 aic_outb(aic
, DMACNTRL0
, INTEN
);
1303 if ((sstat1
& SELTO
) != 0) {
1306 ccb
->ccb_h
.status
= CAM_SEL_TIMEOUT
;
1308 while ((sstat1
& BUSFREE
) == 0)
1309 sstat1
= aic_inb(aic
, SSTAT1
);
1310 aic
->flags
|= AIC_BUSFREE_OK
;
1314 if ((sstat1
& BUSFREE
) != 0) {
1315 aic_outb(aic
, SCSISEQ
, 0);
1316 aic_outb(aic
, CLRSINT0
, sstat0
);
1317 aic_outb(aic
, CLRSINT1
, sstat1
);
1318 if ((scb
= aic
->nexus
)) {
1319 if ((aic
->flags
& AIC_BUSFREE_OK
) == 0) {
1321 ccb
->ccb_h
.status
= CAM_UNEXP_BUSFREE
;
1323 } else if (scb
->flags
& SCB_DEVICE_RESET
) {
1325 if (ccb
->ccb_h
.func_code
== XPT_RESET_DEV
) {
1326 xpt_async(AC_SENT_BDR
,
1327 ccb
->ccb_h
.path
, NULL
);
1328 ccb
->ccb_h
.status
|= CAM_REQ_CMP
;
1330 ccb
->ccb_h
.status
|= CAM_CMD_TIMEOUT
;
1332 } else if (scb
->flags
& SCB_SENSE
) {
1333 /* autosense request */
1334 aic
->flags
&= ~AIC_BUSFREE_OK
;
1335 aic
->tinfo
[scb
->target
].lubusy
&=
1338 aic_outb(aic
, DMACNTRL0
, INTEN
);
1342 aic
->flags
&= ~AIC_BUSFREE_OK
;
1343 aic
->state
= AIC_IDLE
;
1345 aic_outb(aic
, DMACNTRL0
, INTEN
);
1349 if ((sstat1
& REQINIT
) != 0) {
1350 u_int8_t phase
= aic_inb(aic
, SCSISIGI
) & PH_MASK
;
1351 aic_outb(aic
, SCSISIGO
, phase
);
1352 aic_outb(aic
, CLRSINT1
, CLRPHASECHG
);
1364 aic_outb(aic
, DMACNTRL0
, 0);
1365 aic_outb(aic
, SXFRCTL0
, CHEN
|SPIOEN
);
1366 scb
->status
= aic_inb(aic
, SCSIDAT
);
1367 aic_outb(aic
, SXFRCTL0
, CHEN
);
1379 aic
->prev_phase
= phase
;
1380 aic_outb(aic
, DMACNTRL0
, INTEN
);
1384 kprintf("aic_intr: unexpected intr sstat0 %x sstat1 %x\n",
1386 aic_outb(aic
, DMACNTRL0
, INTEN
);
1393 aic_chip_reset(struct aic_softc
*aic
)
1396 * Doc. recommends to clear these two registers before
1397 * operations commence
1399 aic_outb(aic
, SCSITEST
, 0);
1400 aic_outb(aic
, TEST
, 0);
1402 /* Reset SCSI-FIFO and abort any transfers */
1403 aic_outb(aic
, SXFRCTL0
, CHEN
|CLRCH
|CLRSTCNT
);
1405 /* Reset HOST-FIFO */
1406 aic_outb(aic
, DMACNTRL0
, RSTFIFO
);
1407 aic_outb(aic
, DMACNTRL1
, 0);
1409 /* Disable all selection features */
1410 aic_outb(aic
, SCSISEQ
, 0);
1411 aic_outb(aic
, SXFRCTL1
, 0);
1413 /* Disable interrupts */
1414 aic_outb(aic
, SIMODE0
, 0);
1415 aic_outb(aic
, SIMODE1
, 0);
1417 /* Clear interrupts */
1418 aic_outb(aic
, CLRSINT0
, 0x7f);
1419 aic_outb(aic
, CLRSINT1
, 0xef);
1421 /* Disable synchronous transfers */
1422 aic_outb(aic
, SCSIRATE
, 0);
1424 /* Haven't seen ant errors (yet) */
1425 aic_outb(aic
, CLRSERR
, 0x07);
1427 /* Set our SCSI-ID */
1428 aic_outb(aic
, SCSIID
, aic
->initiator
<< OID_S
);
1429 aic_outb(aic
, BRSTCNTRL
, EISA_BRST_TIM
);
1433 * Reset the SCSI bus
1436 aic_scsi_reset(struct aic_softc
*aic
)
1438 aic_outb(aic
, SCSISEQ
, SCSIRSTO
);
1440 aic_outb(aic
, SCSISEQ
, 0);
1445 * Reset. Abort all pending commands.
1448 aic_reset(struct aic_softc
*aic
, int initiate_reset
)
1450 struct ccb_hdr
*ccb_h
;
1452 CAM_DEBUG_PRINT(CAM_DEBUG_TRACE
, ("aic_reset\n"));
1455 aic_scsi_reset(aic
);
1456 aic_chip_reset(aic
);
1458 xpt_async(AC_BUS_RESET
, aic
->path
, NULL
);
1460 while ((ccb_h
= TAILQ_FIRST(&aic
->pending_ccbs
)) != NULL
) {
1461 TAILQ_REMOVE(&aic
->pending_ccbs
, ccb_h
, sim_links
.tqe
);
1462 ccb_h
->status
|= CAM_SCSI_BUS_RESET
;
1463 aic_done(aic
, (struct aic_scb
*)ccb_h
->ccb_scb_ptr
);
1466 while ((ccb_h
= TAILQ_FIRST(&aic
->nexus_ccbs
)) != NULL
) {
1467 TAILQ_REMOVE(&aic
->nexus_ccbs
, ccb_h
, sim_links
.tqe
);
1468 ccb_h
->status
|= CAM_SCSI_BUS_RESET
;
1469 aic_done(aic
, (struct aic_scb
*)ccb_h
->ccb_scb_ptr
);
1473 ccb_h
= &aic
->nexus
->ccb
->ccb_h
;
1474 ccb_h
->status
|= CAM_SCSI_BUS_RESET
;
1475 aic_done(aic
, aic
->nexus
);
1478 aic
->state
= AIC_IDLE
;
1479 aic_outb(aic
, DMACNTRL0
, INTEN
);
1482 static char *aic_chip_names
[] = {
1483 "AIC6260", "AIC6360", "AIC6370", "GM82C700",
1489 } aic_chip_ids
[] = {
1490 { AIC6360
, IDSTRING_AIC6360
},
1491 { AIC6370
, IDSTRING_AIC6370
},
1492 { GM82C700
, IDSTRING_GM82C700
},
1496 aic_init(struct aic_softc
*aic
)
1498 struct aic_scb
*scb
;
1499 struct aic_tinfo
*ti
;
1500 u_int8_t porta
, portb
;
1504 TAILQ_INIT(&aic
->pending_ccbs
);
1505 TAILQ_INIT(&aic
->nexus_ccbs
);
1507 aic
->state
= AIC_IDLE
;
1508 aic
->prev_phase
= -1;
1511 aic_chip_reset(aic
);
1512 aic_scsi_reset(aic
);
1514 /* determine the chip type from its ID string */
1515 aic
->chip_type
= AIC6260
;
1516 aic_insb(aic
, ID
, chip_id
, sizeof(chip_id
) - 1);
1517 chip_id
[sizeof(chip_id
) - 1] = '\0';
1518 for (i
= 0; i
< sizeof(aic_chip_ids
) / sizeof(aic_chip_ids
[0]); i
++) {
1519 if (!strcmp(chip_id
, aic_chip_ids
[i
].idstring
)) {
1520 aic
->chip_type
= aic_chip_ids
[i
].type
;
1525 porta
= aic_inb(aic
, PORTA
);
1526 portb
= aic_inb(aic
, PORTB
);
1528 aic
->initiator
= PORTA_ID(porta
);
1529 if (PORTA_PARITY(porta
))
1530 aic
->flags
|= AIC_PARITY_ENABLE
;
1531 if (PORTB_DISC(portb
))
1532 aic
->flags
|= AIC_DISC_ENABLE
;
1533 if (PORTB_DMA(portb
))
1534 aic
->flags
|= AIC_DMA_ENABLE
;
1537 * We can do fast SCSI (10MHz clock rate) if bit 4 of portb
1538 * is set and we've got a 6360. The 6260 can only do standard
1541 if (aic
->chip_type
> AIC6260
|| aic_inb(aic
, REV
)) {
1542 if (PORTB_FSYNC(portb
))
1543 aic
->flags
|= AIC_FAST_ENABLE
;
1544 aic
->flags
|= AIC_DWIO_ENABLE
;
1547 if (aic
->flags
& AIC_FAST_ENABLE
)
1548 aic
->max_period
= AIC_FAST_SYNC_PERIOD
;
1550 aic
->max_period
= AIC_SYNC_PERIOD
;
1551 aic
->min_period
= AIC_MIN_SYNC_PERIOD
;
1554 for (i
= 255; i
>= 0; i
--) {
1555 scb
= &aic
->scbs
[i
];
1557 aic_free_scb(aic
, scb
);
1560 for (i
= 0; i
< 8; i
++) {
1561 if (i
== aic
->initiator
)
1563 ti
= &aic
->tinfo
[i
];
1564 bzero(ti
, sizeof(*ti
));
1565 ti
->flags
= TINFO_TAG_ENB
;
1566 if (aic
->flags
& AIC_DISC_ENABLE
)
1567 ti
->flags
|= TINFO_DISC_ENB
;
1568 ti
->user
.period
= aic
->max_period
;
1569 ti
->user
.offset
= AIC_SYNC_OFFSET
;
1573 aic_outb(aic
, DMACNTRL0
, INTEN
);
1577 aic_probe(struct aic_softc
*aic
)
1581 /* Remove aic6360 from possible powerdown mode */
1582 aic_outb(aic
, DMACNTRL0
, 0);
1585 aic_outb(aic
, DMACNTRL1
, 0); /* Reset stack pointer */
1586 for (i
= 0; i
< STSIZE
; i
++)
1587 aic_outb(aic
, STACK
, i
);
1589 /* See if we can pull out the same sequence */
1590 aic_outb(aic
, DMACNTRL1
, 0);
1591 for (i
= 0; i
< STSIZE
&& aic_inb(aic
, STACK
) == i
; i
++)
1600 aic_attach(struct aic_softc
*aic
)
1603 * Construct our SIM entry
1605 aic
->sim
= cam_sim_alloc(aic_action
, aic_poll
, "aic", aic
,
1606 aic
->unit
, 2, 256, NULL
);
1607 if (aic
->sim
== NULL
)
1610 if (xpt_bus_register(aic
->sim
, 0) != CAM_SUCCESS
) {
1611 cam_sim_free(aic
->sim
);
1615 if (xpt_create_path(&aic
->path
, /*periph*/NULL
,
1616 cam_sim_path(aic
->sim
), CAM_TARGET_WILDCARD
,
1617 CAM_LUN_WILDCARD
) != CAM_REQ_CMP
) {
1618 xpt_bus_deregister(cam_sim_path(aic
->sim
));
1619 cam_sim_free(aic
->sim
);
1625 kprintf("aic%d: %s", aic
->unit
, aic_chip_names
[aic
->chip_type
]);
1626 if (aic
->flags
& AIC_DMA_ENABLE
)
1628 if (aic
->flags
& AIC_DISC_ENABLE
)
1629 kprintf(", disconnection");
1630 if (aic
->flags
& AIC_PARITY_ENABLE
)
1631 kprintf(", parity check");
1632 if (aic
->flags
& AIC_FAST_ENABLE
)
1633 kprintf(", fast SCSI");
1639 aic_detach(struct aic_softc
*aic
)
1641 xpt_async(AC_LOST_DEVICE
, aic
->path
, NULL
);
1642 xpt_free_path(aic
->path
);
1643 xpt_bus_deregister(cam_sim_path(aic
->sim
));
1644 cam_sim_free(aic
->sim
);