2 * Bus independent FreeBSD shim for the aic7xxx based adaptec SCSI controllers
4 * Copyright (c) 1994-2002 Justin T. Gibbs.
5 * Copyright (c) 2001-2002 Adaptec Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification.
14 * 2. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU Public License ("GPL").
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * $Id: //depot/aic7xxx/freebsd/dev/aic7xxx/aic79xx_osm.c#27 $
34 * $FreeBSD: src/sys/dev/aic7xxx/aic79xx_osm.c,v 1.14 2003/06/14 22:17:39 njl Exp $
35 * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_osm.c,v 1.14 2007/07/03 20:55:42 pavalos Exp $
38 #include "aic79xx_osm.h"
39 #include "aic79xx_inline.h"
46 #ifndef AHD_TMODE_ENABLE
47 #define AHD_TMODE_ENABLE 0
50 #define ccb_scb_ptr spriv_ptr0
53 static void ahd_dump_targcmd(struct target_cmd
*cmd
);
55 static int ahd_modevent(module_t mod
, int type
, void *data
);
56 static void ahd_action(struct cam_sim
*sim
, union ccb
*ccb
);
57 static void ahd_set_tran_settings(struct ahd_softc
*ahd
,
58 int our_id
, char channel
,
59 struct ccb_trans_settings
*cts
);
60 static void ahd_get_tran_settings(struct ahd_softc
*ahd
,
61 int our_id
, char channel
,
62 struct ccb_trans_settings
*cts
);
63 static void ahd_async(void *callback_arg
, uint32_t code
,
64 struct cam_path
*path
, void *arg
);
65 static void ahd_execute_scb(void *arg
, bus_dma_segment_t
*dm_segs
,
66 int nsegments
, int error
);
67 static void ahd_poll(struct cam_sim
*sim
);
68 static void ahd_setup_data(struct ahd_softc
*ahd
, struct cam_sim
*sim
,
69 struct ccb_scsiio
*csio
, struct scb
*scb
);
70 static void ahd_abort_ccb(struct ahd_softc
*ahd
, struct cam_sim
*sim
,
72 static int ahd_create_path(struct ahd_softc
*ahd
,
73 char channel
, u_int target
, u_int lun
,
74 struct cam_path
**path
);
77 static void ahd_set_recoveryscb(struct ahd_softc
*ahd
, struct scb
*scb
);
81 ahd_create_path(struct ahd_softc
*ahd
, char channel
, u_int target
,
82 u_int lun
, struct cam_path
**path
)
87 path_id
= cam_sim_path(ahd
->platform_data
->sim_b
);
89 path_id
= cam_sim_path(ahd
->platform_data
->sim
);
91 return (xpt_create_path(path
, /*periph*/NULL
,
92 path_id
, target
, lun
));
96 ahd_map_int(struct ahd_softc
*ahd
)
100 /* Hook up our interrupt handler */
101 error
= bus_setup_intr(ahd
->dev_softc
, ahd
->platform_data
->irq
,
102 0, ahd_platform_intr
, ahd
,
103 &ahd
->platform_data
->ih
, NULL
);
105 device_printf(ahd
->dev_softc
, "bus_setup_intr() failed: %d\n",
111 * Attach all the sub-devices we can find
114 ahd_attach(struct ahd_softc
*ahd
)
117 struct ccb_setasync csa
;
119 struct cam_path
*path
;
125 ahd_controller_info(ahd
, ahd_info
);
126 kprintf("%s\n", ahd_info
);
130 * Construct our SIM entry
132 sim
= cam_sim_alloc(ahd_action
, ahd_poll
, "ahd", ahd
,
133 device_get_unit(ahd
->dev_softc
),
134 1, AHD_MAX_QUEUE
, NULL
);
138 if (xpt_bus_register(sim
, /*bus_id*/0) != CAM_SUCCESS
) {
144 if (xpt_create_path(&path
, /*periph*/NULL
,
145 cam_sim_path(sim
), CAM_TARGET_WILDCARD
,
146 CAM_LUN_WILDCARD
) != CAM_REQ_CMP
) {
147 xpt_bus_deregister(cam_sim_path(sim
));
153 xpt_setup_ccb(&csa
.ccb_h
, path
, /*priority*/5);
154 csa
.ccb_h
.func_code
= XPT_SASYNC_CB
;
155 csa
.event_enable
= AC_LOST_DEVICE
;
156 csa
.callback
= ahd_async
;
157 csa
.callback_arg
= sim
;
158 xpt_action((union ccb
*)&csa
);
162 ahd
->platform_data
->sim
= sim
;
163 ahd
->platform_data
->path
= path
;
165 /* We have to wait until after any system dumps... */
166 ahd
->platform_data
->eh
=
167 EVENTHANDLER_REGISTER(shutdown_post_sync
, ahd_shutdown
,
168 ahd
, SHUTDOWN_PRI_DEFAULT
);
169 ahd_intr_enable(ahd
, TRUE
);
178 * Catch an interrupt from the adapter
181 ahd_platform_intr(void *arg
)
183 struct ahd_softc
*ahd
;
185 ahd
= (struct ahd_softc
*)arg
;
190 * We have an scb which has been processed by the
191 * adaptor, now we look to see how the operation
195 ahd_done(struct ahd_softc
*ahd
, struct scb
*scb
)
199 CAM_DEBUG(scb
->io_ctx
->ccb_h
.path
, CAM_DEBUG_TRACE
,
200 ("ahd_done - scb %d\n", SCB_GET_TAG(scb
)));
203 LIST_REMOVE(scb
, pending_links
);
205 callout_stop(&ccb
->ccb_h
.timeout_ch
);
207 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
210 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
211 op
= BUS_DMASYNC_POSTREAD
;
213 op
= BUS_DMASYNC_POSTWRITE
;
214 bus_dmamap_sync(ahd
->buffer_dmat
, scb
->dmamap
, op
);
215 bus_dmamap_unload(ahd
->buffer_dmat
, scb
->dmamap
);
218 #ifdef AHD_TARGET_MODE
219 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
220 struct cam_path
*ccb_path
;
223 * If we have finally disconnected, clean up our
224 * pending device state.
225 * XXX - There may be error states that cause where
226 * we will remain connected.
228 ccb_path
= ccb
->ccb_h
.path
;
229 if (ahd
->pending_device
!= NULL
230 && xpt_path_comp(ahd
->pending_device
->path
, ccb_path
) == 0) {
232 if ((ccb
->ccb_h
.flags
& CAM_SEND_STATUS
) != 0) {
233 ahd
->pending_device
= NULL
;
235 xpt_print_path(ccb
->ccb_h
.path
);
236 kprintf("Still disconnected\n");
241 if (ahd_get_transaction_status(scb
) == CAM_REQ_INPROG
)
242 ccb
->ccb_h
.status
|= CAM_REQ_CMP
;
243 ccb
->ccb_h
.status
&= ~CAM_SIM_QUEUED
;
244 ahd_free_scb(ahd
, scb
);
251 * If the recovery SCB completes, we have to be
252 * out of our timeout.
254 if ((scb
->flags
& SCB_RECOVERY_SCB
) != 0) {
255 struct scb
*list_scb
;
258 * We were able to complete the command successfully,
259 * so reinstate the timeouts for all other pending
262 LIST_FOREACH(list_scb
, &ahd
->pending_scbs
, pending_links
) {
266 ccb
= list_scb
->io_ctx
;
267 if (ccb
->ccb_h
.timeout
== CAM_TIME_INFINITY
)
270 time
= ccb
->ccb_h
.timeout
;
273 callout_reset(&ccb
->ccb_h
.timeout_ch
, time
,
274 ahd_timeout
, list_scb
);
277 if (ahd_get_transaction_status(scb
) == CAM_BDR_SENT
278 || ahd_get_transaction_status(scb
) == CAM_REQ_ABORTED
)
279 ahd_set_transaction_status(scb
, CAM_CMD_TIMEOUT
);
280 ahd_print_path(ahd
, scb
);
281 kprintf("no longer in timeout, status = %x\n",
285 /* Don't clobber any existing error state */
286 if (ahd_get_transaction_status(scb
) == CAM_REQ_INPROG
) {
287 ccb
->ccb_h
.status
|= CAM_REQ_CMP
;
288 } else if ((scb
->flags
& SCB_SENSE
) != 0) {
290 * We performed autosense retrieval.
292 * Zero any sense not transferred by the
293 * device. The SCSI spec mandates that any
294 * untransfered data should be assumed to be
295 * zero. Complete the 'bounce' of sense information
296 * through buffers accessible via bus-space by
297 * copying it into the clients csio.
299 memset(&ccb
->csio
.sense_data
, 0, sizeof(ccb
->csio
.sense_data
));
300 memcpy(&ccb
->csio
.sense_data
,
301 ahd_get_sense_buf(ahd
, scb
),
302 /* XXX What size do we want to use??? */
303 sizeof(ccb
->csio
.sense_data
)
304 - ccb
->csio
.sense_resid
);
305 scb
->io_ctx
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
306 } else if ((scb
->flags
& SCB_PKT_SENSE
) != 0) {
307 struct scsi_status_iu_header
*siu
;
312 * Copy only the sense data into the provided buffer.
314 siu
= (struct scsi_status_iu_header
*)scb
->sense_data
;
315 sense_len
= MIN(scsi_4btoul(siu
->sense_length
),
316 sizeof(ccb
->csio
.sense_data
));
317 memset(&ccb
->csio
.sense_data
, 0, sizeof(ccb
->csio
.sense_data
));
318 memcpy(&ccb
->csio
.sense_data
,
319 ahd_get_sense_buf(ahd
, scb
) + SIU_SENSE_OFFSET(siu
),
321 kprintf("Copied %d bytes of sense data offset %d:", sense_len
,
322 SIU_SENSE_OFFSET(siu
));
323 for (i
= 0; i
< sense_len
; i
++)
324 kprintf(" 0x%x", ((uint8_t *)&ccb
->csio
.sense_data
)[i
]);
326 scb
->io_ctx
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
328 ccb
->ccb_h
.status
&= ~CAM_SIM_QUEUED
;
329 ahd_free_scb(ahd
, scb
);
334 ahd_action(struct cam_sim
*sim
, union ccb
*ccb
)
336 struct ahd_softc
*ahd
;
337 #ifdef AHD_TARGET_MODE
338 struct ahd_tmode_lstate
*lstate
;
343 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
, ("ahd_action\n"));
345 ahd
= (struct ahd_softc
*)cam_sim_softc(sim
);
347 target_id
= ccb
->ccb_h
.target_id
;
348 our_id
= SIM_SCSI_ID(ahd
, sim
);
350 switch (ccb
->ccb_h
.func_code
) {
351 /* Common cases first */
352 #ifdef AHD_TARGET_MODE
353 case XPT_ACCEPT_TARGET_IO
: /* Accept Host Target Mode CDB */
354 case XPT_CONT_TARGET_IO
:/* Continue Host Target I/O Connection*/
356 struct ahd_tmode_tstate
*tstate
;
359 status
= ahd_find_tmode_devs(ahd
, sim
, ccb
, &tstate
,
362 if (status
!= CAM_REQ_CMP
) {
363 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
364 /* Response from the black hole device */
366 lstate
= ahd
->black_hole
;
368 ccb
->ccb_h
.status
= status
;
373 if (ccb
->ccb_h
.func_code
== XPT_ACCEPT_TARGET_IO
) {
376 SLIST_INSERT_HEAD(&lstate
->accept_tios
, &ccb
->ccb_h
,
378 ccb
->ccb_h
.status
= CAM_REQ_INPROG
;
379 if ((ahd
->flags
& AHD_TQINFIFO_BLOCKED
) != 0)
380 ahd_run_tqinfifo(ahd
, /*paused*/FALSE
);
386 * The target_id represents the target we attempt to
387 * select. In target mode, this is the initiator of
388 * the original command.
391 target_id
= ccb
->csio
.init_id
;
395 case XPT_SCSI_IO
: /* Execute the requested I/O operation */
396 case XPT_RESET_DEV
: /* Bus Device Reset the specified SCSI device */
399 struct hardware_scb
*hscb
;
400 struct ahd_initiator_tinfo
*tinfo
;
401 struct ahd_tmode_tstate
*tstate
;
404 if ((ahd
->flags
& AHD_INITIATORROLE
) == 0
405 && (ccb
->ccb_h
.func_code
== XPT_SCSI_IO
406 || ccb
->ccb_h
.func_code
== XPT_RESET_DEV
)) {
407 ccb
->ccb_h
.status
= CAM_PROVIDE_FAIL
;
416 tinfo
= ahd_fetch_transinfo(ahd
, 'A', our_id
,
418 if ((ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
) == 0
419 || (tinfo
->curr
.ppr_options
& MSG_EXT_PPR_IU_REQ
) != 0
420 || ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
421 col_idx
= AHD_NEVER_COL_IDX
;
423 col_idx
= AHD_BUILD_COL_IDX(target_id
,
424 ccb
->ccb_h
.target_lun
);
426 if ((scb
= ahd_get_scb(ahd
, col_idx
)) == NULL
) {
428 xpt_freeze_simq(sim
, /*count*/1);
429 ahd
->flags
|= AHD_RESOURCE_SHORTAGE
;
431 ccb
->ccb_h
.status
= CAM_REQUEUE_REQ
;
439 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_SUBTRACE
,
440 ("start scb(%p)\n", scb
));
443 * So we can find the SCB when an abort is requested
445 ccb
->ccb_h
.ccb_scb_ptr
= scb
;
448 * Put all the arguments for the xfer in the scb
451 hscb
->scsiid
= BUILD_SCSIID(ahd
, sim
, target_id
, our_id
);
452 hscb
->lun
= ccb
->ccb_h
.target_lun
;
453 if (ccb
->ccb_h
.func_code
== XPT_RESET_DEV
) {
455 scb
->flags
|= SCB_DEVICE_RESET
;
456 hscb
->control
|= MK_MESSAGE
;
457 hscb
->task_management
= SIU_TASKMGMT_LUN_RESET
;
458 ahd_execute_scb(scb
, NULL
, 0, 0);
460 #ifdef AHD_TARGET_MODE
461 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
462 struct target_data
*tdata
;
464 tdata
= &hscb
->shared_data
.tdata
;
465 if (ahd
->pending_device
== lstate
)
466 scb
->flags
|= SCB_TARGET_IMMEDIATE
;
467 hscb
->control
|= TARGET_SCB
;
468 tdata
->target_phases
= 0;
469 if ((ccb
->ccb_h
.flags
& CAM_SEND_STATUS
) != 0) {
470 tdata
->target_phases
|= SPHASE_PENDING
;
472 ccb
->csio
.scsi_status
;
474 if (ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
)
475 tdata
->target_phases
|= NO_DISCONNECT
;
477 tdata
->initiator_tag
=
478 ahd_htole16(ccb
->csio
.tag_id
);
481 hscb
->task_management
= 0;
482 if (ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
)
483 hscb
->control
|= ccb
->csio
.tag_action
;
485 ahd_setup_data(ahd
, sim
, &ccb
->csio
, scb
);
489 #ifdef AHD_TARGET_MODE
491 case XPT_IMMED_NOTIFY
:
493 struct ahd_tmode_tstate
*tstate
;
494 struct ahd_tmode_lstate
*lstate
;
497 status
= ahd_find_tmode_devs(ahd
, sim
, ccb
, &tstate
,
500 if (status
!= CAM_REQ_CMP
) {
501 ccb
->ccb_h
.status
= status
;
505 SLIST_INSERT_HEAD(&lstate
->immed_notifies
, &ccb
->ccb_h
,
507 ccb
->ccb_h
.status
= CAM_REQ_INPROG
;
508 ahd_send_lstate_events(ahd
, lstate
);
511 case XPT_EN_LUN
: /* Enable LUN as a target */
512 ahd_handle_en_lun(ahd
, sim
, ccb
);
516 case XPT_ABORT
: /* Abort the specified CCB */
518 ahd_abort_ccb(ahd
, sim
, ccb
);
521 case XPT_SET_TRAN_SETTINGS
:
524 ahd_set_tran_settings(ahd
, SIM_SCSI_ID(ahd
, sim
),
525 SIM_CHANNEL(ahd
, sim
), &ccb
->cts
);
530 case XPT_GET_TRAN_SETTINGS
:
531 /* Get default/user set transfer settings for the target */
534 ahd_get_tran_settings(ahd
, SIM_SCSI_ID(ahd
, sim
),
535 SIM_CHANNEL(ahd
, sim
), &ccb
->cts
);
540 case XPT_CALC_GEOMETRY
:
544 extended
= ahd
->flags
& AHD_EXTENDED_TRANS_A
;
545 cam_calc_geometry(&ccb
->ccg
, extended
);
549 case XPT_RESET_BUS
: /* Reset the specified SCSI bus */
554 found
= ahd_reset_channel(ahd
, SIM_CHANNEL(ahd
, sim
),
555 /*initiate reset*/TRUE
);
558 xpt_print_path(SIM_PATH(ahd
, sim
));
559 kprintf("SCSI bus reset delivered. "
560 "%d SCBs aborted.\n", found
);
562 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
566 case XPT_TERM_IO
: /* Terminate the I/O process */
568 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
571 case XPT_PATH_INQ
: /* Path routing inquiry */
573 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
575 cpi
->version_num
= 1; /* XXX??? */
576 cpi
->hba_inquiry
= PI_SDTR_ABLE
|PI_TAG_ABLE
;
577 if ((ahd
->features
& AHD_WIDE
) != 0)
578 cpi
->hba_inquiry
|= PI_WIDE_16
;
579 if ((ahd
->features
& AHD_TARGETMODE
) != 0) {
580 cpi
->target_sprt
= PIT_PROCESSOR
584 cpi
->target_sprt
= 0;
587 cpi
->hba_eng_cnt
= 0;
588 cpi
->max_target
= (ahd
->features
& AHD_WIDE
) ? 15 : 7;
589 cpi
->max_lun
= AHD_NUM_LUNS
- 1;
590 cpi
->initiator_id
= ahd
->our_id
;
591 if ((ahd
->flags
& AHD_RESET_BUS_A
) == 0) {
592 cpi
->hba_misc
|= PIM_NOBUSRESET
;
594 cpi
->bus_id
= cam_sim_bus(sim
);
595 cpi
->base_transfer_speed
= 3300;
596 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
597 strncpy(cpi
->hba_vid
, "Adaptec", HBA_IDLEN
);
598 strncpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
599 cpi
->unit_number
= cam_sim_unit(sim
);
600 #ifdef AHD_NEW_TRAN_SETTINGS
601 cpi
->protocol
= PROTO_SCSI
;
602 cpi
->protocol_version
= SCSI_REV_2
;
603 cpi
->transport
= XPORT_SPI
;
604 cpi
->transport_version
= 2;
605 cpi
->xport_specific
.spi
.ppr_options
= SID_SPI_CLOCK_ST
;
606 cpi
->transport_version
= 4;
607 cpi
->xport_specific
.spi
.ppr_options
= SID_SPI_CLOCK_DT_ST
;
609 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
614 ccb
->ccb_h
.status
= CAM_PROVIDE_FAIL
;
622 ahd_set_tran_settings(struct ahd_softc
*ahd
, int our_id
, char channel
,
623 struct ccb_trans_settings
*cts
)
625 #ifdef AHD_NEW_TRAN_SETTINGS
626 struct ahd_devinfo devinfo
;
627 struct ccb_trans_settings_scsi
*scsi
;
628 struct ccb_trans_settings_spi
*spi
;
629 struct ahd_initiator_tinfo
*tinfo
;
630 struct ahd_tmode_tstate
*tstate
;
631 uint16_t *discenable
;
635 scsi
= &cts
->proto_specific
.scsi
;
636 spi
= &cts
->xport_specific
.spi
;
637 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
638 cts
->ccb_h
.target_id
,
639 cts
->ccb_h
.target_lun
,
640 SIM_CHANNEL(ahd
, sim
),
642 tinfo
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
644 devinfo
.target
, &tstate
);
646 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
) {
647 update_type
|= AHD_TRANS_GOAL
;
648 discenable
= &tstate
->discenable
;
649 tagenable
= &tstate
->tagenable
;
650 tinfo
->curr
.protocol_version
= cts
->protocol_version
;
651 tinfo
->curr
.transport_version
= cts
->transport_version
;
652 tinfo
->goal
.protocol_version
= cts
->protocol_version
;
653 tinfo
->goal
.transport_version
= cts
->transport_version
;
654 } else if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
655 update_type
|= AHD_TRANS_USER
;
656 discenable
= &ahd
->user_discenable
;
657 tagenable
= &ahd
->user_tagenable
;
658 tinfo
->user
.protocol_version
= cts
->protocol_version
;
659 tinfo
->user
.transport_version
= cts
->transport_version
;
661 cts
->ccb_h
.status
= CAM_REQ_INVALID
;
665 if ((spi
->valid
& CTS_SPI_VALID_DISC
) != 0) {
666 if ((spi
->flags
& CTS_SPI_FLAGS_DISC_ENB
) != 0)
667 *discenable
|= devinfo
.target_mask
;
669 *discenable
&= ~devinfo
.target_mask
;
672 if ((scsi
->valid
& CTS_SCSI_VALID_TQ
) != 0) {
673 if ((scsi
->flags
& CTS_SCSI_FLAGS_TAG_ENB
) != 0)
674 *tagenable
|= devinfo
.target_mask
;
676 *tagenable
&= ~devinfo
.target_mask
;
679 if ((spi
->valid
& CTS_SPI_VALID_BUS_WIDTH
) != 0) {
680 ahd_validate_width(ahd
, /*tinfo limit*/NULL
,
681 &spi
->bus_width
, ROLE_UNKNOWN
);
682 ahd_set_width(ahd
, &devinfo
, spi
->bus_width
,
683 update_type
, /*paused*/FALSE
);
686 if ((spi
->valid
& CTS_SPI_VALID_PPR_OPTIONS
) == 0) {
687 if (update_type
== AHD_TRANS_USER
)
688 spi
->ppr_options
= tinfo
->user
.ppr_options
;
690 spi
->ppr_options
= tinfo
->goal
.ppr_options
;
693 if ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) == 0) {
694 if (update_type
== AHD_TRANS_USER
)
695 spi
->sync_offset
= tinfo
->user
.offset
;
697 spi
->sync_offset
= tinfo
->goal
.offset
;
700 if ((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) == 0) {
701 if (update_type
== AHD_TRANS_USER
)
702 spi
->sync_period
= tinfo
->user
.period
;
704 spi
->sync_period
= tinfo
->goal
.period
;
707 if (((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) != 0)
708 || ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) != 0)) {
711 maxsync
= AHD_SYNCRATE_MAX
;
713 if (spi
->bus_width
!= MSG_EXT_WDTR_BUS_16_BIT
)
714 spi
->ppr_options
&= ~MSG_EXT_PPR_DT_REQ
;
716 if ((*discenable
& devinfo
.target_mask
) == 0)
717 spi
->ppr_options
&= ~MSG_EXT_PPR_IU_REQ
;
719 ahd_find_syncrate(ahd
, &spi
->sync_period
,
720 &spi
->ppr_options
, maxsync
);
721 ahd_validate_offset(ahd
, /*tinfo limit*/NULL
,
722 spi
->sync_period
, &spi
->sync_offset
,
723 spi
->bus_width
, ROLE_UNKNOWN
);
725 /* We use a period of 0 to represent async */
726 if (spi
->sync_offset
== 0) {
727 spi
->sync_period
= 0;
728 spi
->ppr_options
= 0;
731 ahd_set_syncrate(ahd
, &devinfo
, spi
->sync_period
,
732 spi
->sync_offset
, spi
->ppr_options
,
733 update_type
, /*paused*/FALSE
);
735 cts
->ccb_h
.status
= CAM_REQ_CMP
;
737 struct ahd_devinfo devinfo
;
738 struct ahd_initiator_tinfo
*tinfo
;
739 struct ahd_tmode_tstate
*tstate
;
740 uint16_t *discenable
;
744 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
745 cts
->ccb_h
.target_id
,
746 cts
->ccb_h
.target_lun
,
747 SIM_CHANNEL(ahd
, sim
),
749 tinfo
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
751 devinfo
.target
, &tstate
);
753 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) != 0) {
754 update_type
|= AHD_TRANS_GOAL
;
755 discenable
= &tstate
->discenable
;
756 tagenable
= &tstate
->tagenable
;
757 } else if ((cts
->flags
& CCB_TRANS_USER_SETTINGS
) != 0) {
758 update_type
|= AHD_TRANS_USER
;
759 discenable
= &ahd
->user_discenable
;
760 tagenable
= &ahd
->user_tagenable
;
762 cts
->ccb_h
.status
= CAM_REQ_INVALID
;
766 if ((cts
->valid
& CCB_TRANS_DISC_VALID
) != 0) {
767 if ((cts
->flags
& CCB_TRANS_DISC_ENB
) != 0)
768 *discenable
|= devinfo
.target_mask
;
770 *discenable
&= ~devinfo
.target_mask
;
773 if ((cts
->valid
& CCB_TRANS_TQ_VALID
) != 0) {
774 if ((cts
->flags
& CCB_TRANS_TAG_ENB
) != 0)
775 *tagenable
|= devinfo
.target_mask
;
777 *tagenable
&= ~devinfo
.target_mask
;
780 if ((cts
->valid
& CCB_TRANS_BUS_WIDTH_VALID
) != 0) {
781 ahd_validate_width(ahd
, /*tinfo limit*/NULL
,
782 &cts
->bus_width
, ROLE_UNKNOWN
);
783 ahd_set_width(ahd
, &devinfo
, cts
->bus_width
,
784 update_type
, /*paused*/FALSE
);
787 if ((cts
->valid
& CCB_TRANS_SYNC_OFFSET_VALID
) == 0) {
788 if (update_type
== AHD_TRANS_USER
)
789 cts
->sync_offset
= tinfo
->user
.offset
;
791 cts
->sync_offset
= tinfo
->goal
.offset
;
794 if ((cts
->valid
& CCB_TRANS_SYNC_RATE_VALID
) == 0) {
795 if (update_type
== AHD_TRANS_USER
)
796 cts
->sync_period
= tinfo
->user
.period
;
798 cts
->sync_period
= tinfo
->goal
.period
;
801 if (((cts
->valid
& CCB_TRANS_SYNC_RATE_VALID
) != 0)
802 || ((cts
->valid
& CCB_TRANS_SYNC_OFFSET_VALID
) != 0)
803 || ((cts
->valid
& CCB_TRANS_TQ_VALID
) != 0)
804 || ((cts
->valid
& CCB_TRANS_DISC_VALID
) != 0)) {
808 maxsync
= AHD_SYNCRATE_MAX
;
810 if (cts
->sync_period
<= AHD_SYNCRATE_DT
811 && cts
->bus_width
== MSG_EXT_WDTR_BUS_16_BIT
) {
812 ppr_options
= tinfo
->user
.ppr_options
813 | MSG_EXT_PPR_DT_REQ
;
816 if ((*tagenable
& devinfo
.target_mask
) == 0
817 || (*discenable
& devinfo
.target_mask
) == 0)
818 ppr_options
&= ~MSG_EXT_PPR_IU_REQ
;
820 ahd_find_syncrate(ahd
, &cts
->sync_period
,
821 &ppr_options
, maxsync
);
822 ahd_validate_offset(ahd
, /*tinfo limit*/NULL
,
823 cts
->sync_period
, &cts
->sync_offset
,
824 MSG_EXT_WDTR_BUS_8_BIT
,
827 /* We use a period of 0 to represent async */
828 if (cts
->sync_offset
== 0) {
829 cts
->sync_period
= 0;
834 && tinfo
->user
.transport_version
>= 3) {
835 tinfo
->goal
.transport_version
=
836 tinfo
->user
.transport_version
;
837 tinfo
->curr
.transport_version
=
838 tinfo
->user
.transport_version
;
841 ahd_set_syncrate(ahd
, &devinfo
, cts
->sync_period
,
842 cts
->sync_offset
, ppr_options
,
843 update_type
, /*paused*/FALSE
);
845 cts
->ccb_h
.status
= CAM_REQ_CMP
;
850 ahd_get_tran_settings(struct ahd_softc
*ahd
, int our_id
, char channel
,
851 struct ccb_trans_settings
*cts
)
853 #ifdef AHD_NEW_TRAN_SETTINGS
854 struct ahd_devinfo devinfo
;
855 struct ccb_trans_settings_scsi
*scsi
;
856 struct ccb_trans_settings_spi
*spi
;
857 struct ahd_initiator_tinfo
*targ_info
;
858 struct ahd_tmode_tstate
*tstate
;
859 struct ahd_transinfo
*tinfo
;
861 scsi
= &cts
->proto_specific
.scsi
;
862 spi
= &cts
->xport_specific
.spi
;
863 ahd_compile_devinfo(&devinfo
, our_id
,
864 cts
->ccb_h
.target_id
,
865 cts
->ccb_h
.target_lun
,
866 channel
, ROLE_UNKNOWN
);
867 targ_info
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
869 devinfo
.target
, &tstate
);
871 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
)
872 tinfo
= &targ_info
->curr
;
874 tinfo
= &targ_info
->user
;
876 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
877 spi
->flags
&= ~CTS_SPI_FLAGS_DISC_ENB
;
878 if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
879 if ((ahd
->user_discenable
& devinfo
.target_mask
) != 0)
880 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
882 if ((ahd
->user_tagenable
& devinfo
.target_mask
) != 0)
883 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
885 if ((tstate
->discenable
& devinfo
.target_mask
) != 0)
886 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
888 if ((tstate
->tagenable
& devinfo
.target_mask
) != 0)
889 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
891 cts
->protocol_version
= tinfo
->protocol_version
;
892 cts
->transport_version
= tinfo
->transport_version
;
894 spi
->sync_period
= tinfo
->period
;
895 spi
->sync_offset
= tinfo
->offset
;
896 spi
->bus_width
= tinfo
->width
;
897 spi
->ppr_options
= tinfo
->ppr_options
;
899 cts
->protocol
= PROTO_SCSI
;
900 cts
->transport
= XPORT_SPI
;
901 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
902 | CTS_SPI_VALID_SYNC_OFFSET
903 | CTS_SPI_VALID_BUS_WIDTH
904 | CTS_SPI_VALID_PPR_OPTIONS
;
906 if (cts
->ccb_h
.target_lun
!= CAM_LUN_WILDCARD
) {
907 scsi
->valid
= CTS_SCSI_VALID_TQ
;
908 spi
->valid
|= CTS_SPI_VALID_DISC
;
913 cts
->ccb_h
.status
= CAM_REQ_CMP
;
915 struct ahd_devinfo devinfo
;
916 struct ahd_initiator_tinfo
*targ_info
;
917 struct ahd_tmode_tstate
*tstate
;
918 struct ahd_transinfo
*tinfo
;
920 ahd_compile_devinfo(&devinfo
, our_id
,
921 cts
->ccb_h
.target_id
,
922 cts
->ccb_h
.target_lun
,
923 channel
, ROLE_UNKNOWN
);
924 targ_info
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
926 devinfo
.target
, &tstate
);
928 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) != 0)
929 tinfo
= &targ_info
->curr
;
931 tinfo
= &targ_info
->user
;
933 cts
->flags
&= ~(CCB_TRANS_DISC_ENB
|CCB_TRANS_TAG_ENB
);
934 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) == 0) {
935 if ((ahd
->user_discenable
& devinfo
.target_mask
) != 0)
936 cts
->flags
|= CCB_TRANS_DISC_ENB
;
938 if ((ahd
->user_tagenable
& devinfo
.target_mask
) != 0)
939 cts
->flags
|= CCB_TRANS_TAG_ENB
;
941 if ((tstate
->discenable
& devinfo
.target_mask
) != 0)
942 cts
->flags
|= CCB_TRANS_DISC_ENB
;
944 if ((tstate
->tagenable
& devinfo
.target_mask
) != 0)
945 cts
->flags
|= CCB_TRANS_TAG_ENB
;
947 cts
->sync_period
= tinfo
->period
;
948 cts
->sync_offset
= tinfo
->offset
;
949 cts
->bus_width
= tinfo
->width
;
951 cts
->valid
= CCB_TRANS_SYNC_RATE_VALID
952 | CCB_TRANS_SYNC_OFFSET_VALID
953 | CCB_TRANS_BUS_WIDTH_VALID
;
955 if (cts
->ccb_h
.target_lun
!= CAM_LUN_WILDCARD
)
956 cts
->valid
|= CCB_TRANS_DISC_VALID
|CCB_TRANS_TQ_VALID
;
958 cts
->ccb_h
.status
= CAM_REQ_CMP
;
963 ahd_async(void *callback_arg
, uint32_t code
, struct cam_path
*path
, void *arg
)
965 struct ahd_softc
*ahd
;
968 sim
= (struct cam_sim
*)callback_arg
;
969 ahd
= (struct ahd_softc
*)cam_sim_softc(sim
);
973 struct ahd_devinfo devinfo
;
975 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
976 xpt_path_target_id(path
),
977 xpt_path_lun_id(path
),
978 SIM_CHANNEL(ahd
, sim
),
982 * Revert to async/narrow transfers
983 * for the next device.
986 ahd_set_width(ahd
, &devinfo
, MSG_EXT_WDTR_BUS_8_BIT
,
987 AHD_TRANS_GOAL
|AHD_TRANS_CUR
, /*paused*/FALSE
);
988 ahd_set_syncrate(ahd
, &devinfo
, /*period*/0, /*offset*/0,
989 /*ppr_options*/0, AHD_TRANS_GOAL
|AHD_TRANS_CUR
,
1000 ahd_execute_scb(void *arg
, bus_dma_segment_t
*dm_segs
, int nsegments
,
1005 struct ahd_softc
*ahd
;
1006 struct ahd_initiator_tinfo
*tinfo
;
1007 struct ahd_tmode_tstate
*tstate
;
1010 scb
= (struct scb
*)arg
;
1012 ahd
= scb
->ahd_softc
;
1016 ahd_set_transaction_status(scb
, CAM_REQ_TOO_BIG
);
1018 ahd_set_transaction_status(scb
, CAM_REQ_CMP_ERR
);
1020 bus_dmamap_unload(ahd
->buffer_dmat
, scb
->dmamap
);
1022 ahd_free_scb(ahd
, scb
);
1028 if (nsegments
!= 0) {
1030 bus_dmasync_op_t op
;
1033 /* Copy the segments into our SG list */
1034 for (i
= nsegments
, sg
= scb
->sg_list
; i
> 0; i
--) {
1036 sg
= ahd_sg_setup(ahd
, scb
, sg
, dm_segs
->ds_addr
,
1042 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
1043 op
= BUS_DMASYNC_PREREAD
;
1045 op
= BUS_DMASYNC_PREWRITE
;
1047 bus_dmamap_sync(ahd
->buffer_dmat
, scb
->dmamap
, op
);
1049 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
1050 struct target_data
*tdata
;
1052 tdata
= &scb
->hscb
->shared_data
.tdata
;
1053 tdata
->target_phases
|= DPHASE_PENDING
;
1054 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_OUT
)
1055 tdata
->data_phase
= P_DATAOUT
;
1057 tdata
->data_phase
= P_DATAIN
;
1064 * Last time we need to check if this SCB needs to
1067 if (ahd_get_transaction_status(scb
) != CAM_REQ_INPROG
) {
1069 bus_dmamap_unload(ahd
->buffer_dmat
,
1071 ahd_free_scb(ahd
, scb
);
1077 tinfo
= ahd_fetch_transinfo(ahd
, SCSIID_CHANNEL(ahd
, scb
->hscb
->scsiid
),
1078 SCSIID_OUR_ID(scb
->hscb
->scsiid
),
1079 SCSIID_TARGET(ahd
, scb
->hscb
->scsiid
),
1082 mask
= SCB_GET_TARGET_MASK(ahd
, scb
);
1084 if ((tstate
->discenable
& mask
) != 0
1085 && (ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
) == 0)
1086 scb
->hscb
->control
|= DISCENB
;
1088 if ((tinfo
->curr
.ppr_options
& MSG_EXT_PPR_IU_REQ
) != 0) {
1089 scb
->flags
|= SCB_PACKETIZED
;
1090 if (scb
->hscb
->task_management
!= 0)
1091 scb
->hscb
->control
&= ~MK_MESSAGE
;
1094 if ((ccb
->ccb_h
.flags
& CAM_NEGOTIATE
) != 0
1095 && (tinfo
->goal
.width
!= 0
1096 || tinfo
->goal
.period
!= 0
1097 || tinfo
->goal
.ppr_options
!= 0)) {
1098 scb
->flags
|= SCB_NEGOTIATE
;
1099 scb
->hscb
->control
|= MK_MESSAGE
;
1100 } else if ((tstate
->auto_negotiate
& mask
) != 0) {
1101 scb
->flags
|= SCB_AUTO_NEGOTIATE
;
1102 scb
->hscb
->control
|= MK_MESSAGE
;
1105 LIST_INSERT_HEAD(&ahd
->pending_scbs
, scb
, pending_links
);
1107 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
1109 if (ccb
->ccb_h
.timeout
!= CAM_TIME_INFINITY
) {
1112 if (ccb
->ccb_h
.timeout
== CAM_TIME_DEFAULT
)
1113 ccb
->ccb_h
.timeout
= 5 * 1000;
1115 time
= ccb
->ccb_h
.timeout
;
1118 callout_reset(&ccb
->ccb_h
.timeout_ch
, time
, ahd_timeout
, scb
);
1121 if ((scb
->flags
& SCB_TARGET_IMMEDIATE
) != 0) {
1122 /* Define a mapping from our tag to the SCB. */
1123 ahd
->scb_data
.scbindex
[SCB_GET_TAG(scb
)] = scb
;
1125 ahd_set_scbptr(ahd
, SCB_GET_TAG(scb
));
1126 ahd_outb(ahd
, RETURN_1
, CONT_MSG_LOOP_TARG
);
1129 ahd_queue_scb(ahd
, scb
);
1136 ahd_poll(struct cam_sim
*sim
)
1138 ahd_intr(cam_sim_softc(sim
));
1142 ahd_setup_data(struct ahd_softc
*ahd
, struct cam_sim
*sim
,
1143 struct ccb_scsiio
*csio
, struct scb
*scb
)
1145 struct hardware_scb
*hscb
;
1146 struct ccb_hdr
*ccb_h
;
1149 ccb_h
= &csio
->ccb_h
;
1152 csio
->sense_resid
= 0;
1153 if (ccb_h
->func_code
== XPT_SCSI_IO
) {
1154 hscb
->cdb_len
= csio
->cdb_len
;
1155 if ((ccb_h
->flags
& CAM_CDB_POINTER
) != 0) {
1157 if (hscb
->cdb_len
> MAX_CDB_LEN
1158 && (ccb_h
->flags
& CAM_CDB_PHYS
) == 0) {
1160 * Should CAM start to support CDB sizes
1161 * greater than 16 bytes, we could use
1162 * the sense buffer to store the CDB.
1164 ahd_set_transaction_status(scb
,
1167 ahd_free_scb(ahd
, scb
);
1169 xpt_done((union ccb
*)csio
);
1172 if ((ccb_h
->flags
& CAM_CDB_PHYS
) != 0) {
1173 hscb
->shared_data
.idata
.cdb_from_host
.cdbptr
=
1174 ahd_htole64((uintptr_t)csio
->cdb_io
.cdb_ptr
);
1175 hscb
->shared_data
.idata
.cdb_from_host
.cdblen
=
1177 hscb
->cdb_len
|= SCB_CDB_LEN_PTR
;
1179 memcpy(hscb
->shared_data
.idata
.cdb
,
1180 csio
->cdb_io
.cdb_ptr
,
1184 if (hscb
->cdb_len
> MAX_CDB_LEN
) {
1185 ahd_set_transaction_status(scb
,
1188 ahd_free_scb(ahd
, scb
);
1190 xpt_done((union ccb
*)csio
);
1193 memcpy(hscb
->shared_data
.idata
.cdb
,
1194 csio
->cdb_io
.cdb_bytes
, hscb
->cdb_len
);
1198 /* Only use S/G if there is a transfer */
1199 if ((ccb_h
->flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
1200 if ((ccb_h
->flags
& CAM_SCATTER_VALID
) == 0) {
1201 /* We've been given a pointer to a single buffer */
1202 if ((ccb_h
->flags
& CAM_DATA_PHYS
) == 0) {
1206 error
= bus_dmamap_load(ahd
->buffer_dmat
,
1212 if (error
== EINPROGRESS
) {
1214 * So as to maintain ordering,
1215 * freeze the controller queue
1216 * until our mapping is
1219 xpt_freeze_simq(sim
,
1221 scb
->io_ctx
->ccb_h
.status
|=
1226 struct bus_dma_segment seg
;
1228 /* Pointer to physical buffer */
1229 if (csio
->dxfer_len
> AHD_MAXTRANSFER_SIZE
)
1230 panic("ahd_setup_data - Transfer size "
1231 "larger than can device max");
1234 (bus_addr_t
)(vm_offset_t
)csio
->data_ptr
;
1235 seg
.ds_len
= csio
->dxfer_len
;
1236 ahd_execute_scb(scb
, &seg
, 1, 0);
1239 struct bus_dma_segment
*segs
;
1241 if ((ccb_h
->flags
& CAM_DATA_PHYS
) != 0)
1242 panic("ahd_setup_data - Physical segment "
1243 "pointers unsupported");
1245 if ((ccb_h
->flags
& CAM_SG_LIST_PHYS
) == 0)
1246 panic("ahd_setup_data - Virtual segment "
1247 "addresses unsupported");
1249 /* Just use the segments provided */
1250 segs
= (struct bus_dma_segment
*)csio
->data_ptr
;
1251 ahd_execute_scb(scb
, segs
, csio
->sglist_cnt
, 0);
1254 ahd_execute_scb(scb
, NULL
, 0, 0);
1260 ahd_set_recoveryscb(struct ahd_softc
*ahd
, struct scb
*scb
) {
1262 if ((scb
->flags
& SCB_RECOVERY_SCB
) == 0) {
1263 struct scb
*list_scb
;
1265 scb
->flags
|= SCB_RECOVERY_SCB
;
1268 * Take all queued, but not sent SCBs out of the equation.
1269 * Also ensure that no new CCBs are queued to us while we
1270 * try to fix this problem.
1272 if ((scb
->io_ctx
->ccb_h
.status
& CAM_RELEASE_SIMQ
) == 0) {
1273 xpt_freeze_simq(SCB_GET_SIM(ahd
, scb
), /*count*/1);
1274 scb
->io_ctx
->ccb_h
.status
|= CAM_RELEASE_SIMQ
;
1278 * Go through all of our pending SCBs and remove
1279 * any scheduled timeouts for them. We will reschedule
1280 * them after we've successfully fixed this problem.
1282 LIST_FOREACH(list_scb
, &ahd
->pending_scbs
, pending_links
) {
1285 ccb
= list_scb
->io_ctx
;
1286 callout_stop(&ccb
->ccb_h
.timeout_ch
);
1293 ahd_timeout(void *arg
)
1296 struct ahd_softc
*ahd
;
1297 ahd_mode_state saved_modes
;
1308 scb
= (struct scb
*)arg
;
1309 ahd
= (struct ahd_softc
*)scb
->ahd_softc
;
1313 ahd_pause_and_flushwork(ahd
);
1315 saved_modes
= ahd_save_modes(ahd
);
1317 ahd_set_modes(ahd
, AHD_MODE_SCSI
, AHD_MODE_SCSI
);
1318 ahd_outb(ahd
, SCSISIGO
, ACKO
);
1319 kprintf("set ACK\n");
1320 ahd_outb(ahd
, SCSISIGO
, 0);
1321 kprintf("clearing Ack\n");
1322 ahd_restore_modes(ahd
, saved_modes
);
1324 if ((scb
->flags
& SCB_ACTIVE
) == 0) {
1325 /* Previous timeout took care of me already */
1326 kprintf("%s: Timedout SCB already complete. "
1327 "Interrupts may not be functioning.\n", ahd_name(ahd
));
1333 target
= SCB_GET_TARGET(ahd
, scb
);
1334 channel
= SCB_GET_CHANNEL(ahd
, scb
);
1335 lun
= SCB_GET_LUN(scb
);
1337 ahd_print_path(ahd
, scb
);
1338 kprintf("SCB 0x%x - timed out\n", SCB_GET_TAG(scb
));
1339 ahd_dump_card_state(ahd
);
1340 ahd_reset_channel(ahd
, SIM_CHANNEL(ahd
, sim
),
1341 /*initiate reset*/TRUE
);
1345 last_phase
= ahd_inb(ahd
, LASTPHASE
);
1346 if (scb
->sg_count
> 0) {
1347 for (i
= 0; i
< scb
->sg_count
; i
++) {
1348 kprintf("sg[%d] - Addr 0x%x : Length %d\n",
1350 ((struct ahd_dma_seg
*)scb
->sg_list
)[i
].addr
,
1351 ((struct ahd_dma_seg
*)scb
->sg_list
)[i
].len
1355 if (scb
->flags
& (SCB_DEVICE_RESET
|SCB_ABORT
)) {
1357 * Been down this road before.
1358 * Do a full bus reset.
1361 ahd_set_transaction_status(scb
, CAM_CMD_TIMEOUT
);
1362 found
= ahd_reset_channel(ahd
, channel
, /*Initiate Reset*/TRUE
);
1363 kprintf("%s: Issued Channel %c Bus Reset. "
1364 "%d SCBs aborted\n", ahd_name(ahd
), channel
, found
);
1367 * If we are a target, transition to bus free and report
1370 * The target/initiator that is holding up the bus may not
1371 * be the same as the one that triggered this timeout
1372 * (different commands have different timeout lengths).
1373 * If the bus is idle and we are actiing as the initiator
1374 * for this request, queue a BDR message to the timed out
1375 * target. Otherwise, if the timed out transaction is
1377 * Initiator transaction:
1378 * Stuff the message buffer with a BDR message and assert
1379 * ATN in the hopes that the target will let go of the bus
1380 * and go to the mesgout phase. If this fails, we'll
1381 * get another timeout 2 seconds later which will attempt
1384 * Target transaction:
1385 * Transition to BUS FREE and report the error.
1386 * It's good to be the target!
1388 u_int active_scb_index
;
1391 saved_scbptr
= ahd_get_scbptr(ahd
);
1392 active_scb_index
= saved_scbptr
;
1394 if (last_phase
!= P_BUSFREE
1395 && (ahd_inb(ahd
, SEQ_FLAGS
) & NOT_IDENTIFIED
) == 0
1396 && (active_scb_index
< ahd
->scb_data
.numscbs
)) {
1397 struct scb
*active_scb
;
1400 * If the active SCB is not us, assume that
1401 * the active SCB has a longer timeout than
1402 * the timedout SCB, and wait for the active
1405 active_scb
= ahd_lookup_scb(ahd
, active_scb_index
);
1406 if (active_scb
!= scb
) {
1407 struct ccb_hdr
*ccbh
;
1408 uint64_t newtimeout
;
1410 ahd_print_path(ahd
, scb
);
1411 kprintf("Other SCB Timeout%s",
1412 (scb
->flags
& SCB_OTHERTCL_TIMEOUT
) != 0
1413 ? " again\n" : "\n");
1414 scb
->flags
|= SCB_OTHERTCL_TIMEOUT
;
1416 MAX(active_scb
->io_ctx
->ccb_h
.timeout
,
1417 scb
->io_ctx
->ccb_h
.timeout
);
1420 ccbh
= &scb
->io_ctx
->ccb_h
;
1421 callout_reset(&scb
->io_ctx
->ccb_h
.timeout_ch
,
1422 newtimeout
, ahd_timeout
, scb
);
1429 if ((scb
->hscb
->control
& TARGET_SCB
) != 0) {
1432 * Send back any queued up transactions
1433 * and properly record the error condition.
1435 ahd_abort_scbs(ahd
, SCB_GET_TARGET(ahd
, scb
),
1436 SCB_GET_CHANNEL(ahd
, scb
),
1442 /* Will clear us from the bus */
1448 ahd_set_recoveryscb(ahd
, active_scb
);
1449 ahd_outb(ahd
, MSG_OUT
, HOST_MSG
);
1450 ahd_outb(ahd
, SCSISIGO
, last_phase
|ATNO
);
1451 ahd_print_path(ahd
, active_scb
);
1452 kprintf("BDR message in message buffer\n");
1453 active_scb
->flags
|= SCB_DEVICE_RESET
;
1454 callout_reset(&active_scb
->io_ctx
->ccb_h
.timeout_ch
,
1455 2 * hz
, ahd_timeout
, active_scb
);
1460 /* XXX Shouldn't panic. Just punt instead? */
1461 if ((scb
->hscb
->control
& TARGET_SCB
) != 0)
1462 panic("Timed-out target SCB but bus idle");
1464 if (last_phase
!= P_BUSFREE
1465 && (ahd_inb(ahd
, SSTAT0
) & TARGET
) != 0) {
1466 /* XXX What happened to the SCB? */
1467 /* Hung target selection. Goto busfree */
1468 kprintf("%s: Hung target selection\n",
1475 if (ahd_search_qinfifo(ahd
, target
, channel
, lun
,
1476 SCB_GET_TAG(scb
), ROLE_INITIATOR
,
1477 /*status*/0, SEARCH_COUNT
) > 0) {
1478 disconnected
= FALSE
;
1480 disconnected
= TRUE
;
1485 ahd_set_recoveryscb(ahd
, scb
);
1487 * Actually re-queue this SCB in an attempt
1488 * to select the device before it reconnects.
1489 * In either case (selection or reselection),
1490 * we will now issue a target reset to the
1493 * Set the MK_MESSAGE control bit indicating
1494 * that we desire to send a message. We
1495 * also set the disconnected flag since
1496 * in the paging case there is no guarantee
1497 * that our SCB control byte matches the
1498 * version on the card. We don't want the
1499 * sequencer to abort the command thinking
1500 * an unsolicited reselection occurred.
1502 scb
->hscb
->control
|= MK_MESSAGE
|DISCONNECTED
;
1503 scb
->flags
|= SCB_DEVICE_RESET
;
1506 * The sequencer will never re-reference the
1507 * in-core SCB. To make sure we are notified
1508 * during reslection, set the MK_MESSAGE flag
1509 * in the card's copy of the SCB.
1511 ahd_set_scbptr(ahd
, SCB_GET_TAG(scb
));
1512 ahd_outb(ahd
, SCB_CONTROL
,
1513 ahd_inb(ahd
, SCB_CONTROL
)|MK_MESSAGE
);
1516 * Clear out any entries in the QINFIFO first
1517 * so we are the next SCB for this target
1520 ahd_search_qinfifo(ahd
,
1521 SCB_GET_TARGET(ahd
, scb
),
1522 channel
, SCB_GET_LUN(scb
),
1527 ahd_print_path(ahd
, scb
);
1528 kprintf("Queuing a BDR SCB\n");
1529 ahd_qinfifo_requeue_tail(ahd
, scb
);
1530 ahd_set_scbptr(ahd
, saved_scbptr
);
1531 callout_reset(&scb
->io_ctx
->ccb_h
.timeout_ch
,
1532 2 * hz
, ahd_timeout
, scb
);
1535 /* Go "immediatly" to the bus reset */
1536 /* This shouldn't happen */
1537 ahd_set_recoveryscb(ahd
, scb
);
1538 ahd_print_path(ahd
, scb
);
1539 kprintf("SCB %d: Immediate reset. "
1540 "Flags = 0x%x\n", SCB_GET_TAG(scb
),
1551 ahd_abort_ccb(struct ahd_softc
*ahd
, struct cam_sim
*sim
, union ccb
*ccb
)
1553 union ccb
*abort_ccb
;
1555 abort_ccb
= ccb
->cab
.abort_ccb
;
1556 switch (abort_ccb
->ccb_h
.func_code
) {
1557 #ifdef AHD_TARGET_MODE
1558 case XPT_ACCEPT_TARGET_IO
:
1559 case XPT_IMMED_NOTIFY
:
1560 case XPT_CONT_TARGET_IO
:
1562 struct ahd_tmode_tstate
*tstate
;
1563 struct ahd_tmode_lstate
*lstate
;
1564 struct ccb_hdr_slist
*list
;
1567 status
= ahd_find_tmode_devs(ahd
, sim
, abort_ccb
, &tstate
,
1570 if (status
!= CAM_REQ_CMP
) {
1571 ccb
->ccb_h
.status
= status
;
1575 if (abort_ccb
->ccb_h
.func_code
== XPT_ACCEPT_TARGET_IO
)
1576 list
= &lstate
->accept_tios
;
1577 else if (abort_ccb
->ccb_h
.func_code
== XPT_IMMED_NOTIFY
)
1578 list
= &lstate
->immed_notifies
;
1583 struct ccb_hdr
*curelm
;
1586 curelm
= SLIST_FIRST(list
);
1588 if (curelm
== &abort_ccb
->ccb_h
) {
1590 SLIST_REMOVE_HEAD(list
, sim_links
.sle
);
1592 while(curelm
!= NULL
) {
1593 struct ccb_hdr
*nextelm
;
1596 SLIST_NEXT(curelm
, sim_links
.sle
);
1598 if (nextelm
== &abort_ccb
->ccb_h
) {
1611 abort_ccb
->ccb_h
.status
= CAM_REQ_ABORTED
;
1612 xpt_done(abort_ccb
);
1613 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1615 xpt_print_path(abort_ccb
->ccb_h
.path
);
1616 kprintf("Not found\n");
1617 ccb
->ccb_h
.status
= CAM_PATH_INVALID
;
1625 /* XXX Fully implement the hard ones */
1626 ccb
->ccb_h
.status
= CAM_UA_ABORT
;
1629 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1636 ahd_send_async(struct ahd_softc
*ahd
, char channel
, u_int target
,
1637 u_int lun
, ac_code code
, void *opt_arg
)
1639 struct ccb_trans_settings cts
;
1640 struct cam_path
*path
;
1645 error
= ahd_create_path(ahd
, channel
, target
, lun
, &path
);
1647 if (error
!= CAM_REQ_CMP
)
1651 case AC_TRANSFER_NEG
:
1653 #ifdef AHD_NEW_TRAN_SETTINGS
1654 struct ccb_trans_settings_scsi
*scsi
;
1656 cts
.type
= CTS_TYPE_CURRENT_SETTINGS
;
1657 scsi
= &cts
.proto_specific
.scsi
;
1659 cts
.flags
= CCB_TRANS_CURRENT_SETTINGS
;
1661 cts
.ccb_h
.path
= path
;
1662 cts
.ccb_h
.target_id
= target
;
1663 cts
.ccb_h
.target_lun
= lun
;
1664 ahd_get_tran_settings(ahd
, ahd
->our_id
, channel
, &cts
);
1666 #ifdef AHD_NEW_TRAN_SETTINGS
1667 scsi
->valid
&= ~CTS_SCSI_VALID_TQ
;
1668 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
1670 cts
.valid
&= ~CCB_TRANS_TQ_VALID
;
1671 cts
.flags
&= ~CCB_TRANS_TAG_ENB
;
1673 if (opt_arg
== NULL
)
1675 if (*((ahd_queue_alg
*)opt_arg
) == AHD_QUEUE_TAGGED
)
1676 #ifdef AHD_NEW_TRAN_SETTINGS
1677 scsi
->flags
|= ~CTS_SCSI_FLAGS_TAG_ENB
;
1678 scsi
->valid
|= CTS_SCSI_VALID_TQ
;
1680 cts
.flags
|= CCB_TRANS_TAG_ENB
;
1681 cts
.valid
|= CCB_TRANS_TQ_VALID
;
1689 panic("ahd_send_async: Unexpected async event");
1691 xpt_async(code
, path
, arg
);
1692 xpt_free_path(path
);
1696 ahd_platform_set_tags(struct ahd_softc
*ahd
,
1697 struct ahd_devinfo
*devinfo
, int enable
)
1702 ahd_platform_alloc(struct ahd_softc
*ahd
, void *platform_arg
)
1704 ahd
->platform_data
= kmalloc(sizeof(struct ahd_platform_data
), M_DEVBUF
,
1705 M_INTWAIT
| M_ZERO
);
1710 ahd_platform_free(struct ahd_softc
*ahd
)
1712 struct ahd_platform_data
*pdata
;
1714 pdata
= ahd
->platform_data
;
1715 if (pdata
!= NULL
) {
1716 if (pdata
->regs
[0] != NULL
)
1717 bus_release_resource(ahd
->dev_softc
,
1718 pdata
->regs_res_type
[0],
1719 pdata
->regs_res_id
[0],
1722 if (pdata
->regs
[1] != NULL
)
1723 bus_release_resource(ahd
->dev_softc
,
1724 pdata
->regs_res_type
[1],
1725 pdata
->regs_res_id
[1],
1728 if (pdata
->irq
!= NULL
)
1729 bus_release_resource(ahd
->dev_softc
,
1730 pdata
->irq_res_type
,
1733 if (pdata
->sim_b
!= NULL
) {
1734 xpt_async(AC_LOST_DEVICE
, pdata
->path_b
, NULL
);
1735 xpt_free_path(pdata
->path_b
);
1736 xpt_bus_deregister(cam_sim_path(pdata
->sim_b
));
1737 cam_sim_free(pdata
->sim_b
);
1739 if (pdata
->sim
!= NULL
) {
1740 xpt_async(AC_LOST_DEVICE
, pdata
->path
, NULL
);
1741 xpt_free_path(pdata
->path
);
1742 xpt_bus_deregister(cam_sim_path(pdata
->sim
));
1743 cam_sim_free(pdata
->sim
);
1745 if (pdata
->eh
!= NULL
)
1746 EVENTHANDLER_DEREGISTER(shutdown_post_sync
, pdata
->eh
);
1747 kfree(ahd
->platform_data
, M_DEVBUF
);
1752 ahd_softc_comp(struct ahd_softc
*lahd
, struct ahd_softc
*rahd
)
1754 /* We don't sort softcs under FreeBSD so report equal always */
1759 ahd_detach(device_t dev
)
1761 struct ahd_softc
*ahd
;
1763 device_printf(dev
, "detaching device\n");
1764 ahd
= device_get_softc(dev
);
1765 ahd
= ahd_find_softc(ahd
);
1767 device_printf(dev
, "aic7xxx already detached\n");
1771 ahd_intr_enable(ahd
, FALSE
);
1772 bus_teardown_intr(dev
, ahd
->platform_data
->irq
, ahd
->platform_data
->ih
);
1780 ahd_dump_targcmd(struct target_cmd
*cmd
)
1786 byte
= &cmd
->initiator_channel
;
1787 /* Debugging info for received commands */
1788 last_byte
= &cmd
[1].initiator_channel
;
1791 while (byte
< last_byte
) {
1794 kprintf("%#x", *byte
++);
1807 ahd_modevent(module_t mod
, int type
, void *data
)
1809 /* XXX Deal with busy status on unload. */
1813 static moduledata_t ahd_mod
= {
1819 /********************************** DDB Hooks *********************************/
1821 static struct ahd_softc
*ahd_ddb_softc
;
1822 static int ahd_ddb_paused
;
1823 static int ahd_ddb_paused_on_entry
;
1824 DB_COMMAND(ahd_set_unit
, ahd_ddb_set_unit
)
1826 struct ahd_softc
*list_ahd
;
1828 ahd_ddb_softc
= NULL
;
1829 TAILQ_FOREACH(list_ahd
, &ahd_tailq
, links
) {
1830 if (list_ahd
->unit
== addr
)
1831 ahd_ddb_softc
= list_ahd
;
1833 if (ahd_ddb_softc
== NULL
)
1834 db_error("No matching softc found!\n");
1837 DB_COMMAND(ahd_pause
, ahd_ddb_pause
)
1839 if (ahd_ddb_softc
== NULL
) {
1840 db_error("Must set unit with ahd_set_unit first!\n");
1843 if (ahd_ddb_paused
== 0) {
1845 if (ahd_is_paused(ahd_ddb_softc
)) {
1846 ahd_ddb_paused_on_entry
++;
1849 ahd_pause(ahd_ddb_softc
);
1853 DB_COMMAND(ahd_unpause
, ahd_ddb_unpause
)
1855 if (ahd_ddb_softc
== NULL
) {
1856 db_error("Must set unit with ahd_set_unit first!\n");
1859 if (ahd_ddb_paused
!= 0) {
1861 if (ahd_ddb_paused_on_entry
)
1863 ahd_unpause(ahd_ddb_softc
);
1864 } else if (ahd_ddb_paused_on_entry
!= 0) {
1865 /* Two unpauses to clear a paused on entry. */
1866 ahd_ddb_paused_on_entry
= 0;
1867 ahd_unpause(ahd_ddb_softc
);
1871 DB_COMMAND(ahd_in
, ahd_ddb_in
)
1876 if (ahd_ddb_softc
== NULL
) {
1877 db_error("Must set unit with ahd_set_unit first!\n");
1884 while ((c
= *modif
++) != '\0') {
1900 while (--count
>= 0) {
1901 db_printf("%04lx (M)%x: \t", (u_long
)addr
,
1902 ahd_inb(ahd_ddb_softc
, MODE_PTR
));
1905 db_printf("%02x\n", ahd_inb(ahd_ddb_softc
, addr
));
1908 db_printf("%04x\n", ahd_inw(ahd_ddb_softc
, addr
));
1911 db_printf("%08x\n", ahd_inl(ahd_ddb_softc
, addr
));
1917 DB_SET(ahd_out
, ahd_ddb_out
, db_cmd_set
, CS_MORE
, NULL
)
1919 db_expr_t old_value
;
1920 db_expr_t new_value
;
1923 if (ahd_ddb_softc
== NULL
) {
1924 db_error("Must set unit with ahd_set_unit first!\n");
1940 db_error("Unknown size\n");
1944 while (db_expression(&new_value
)) {
1948 old_value
= ahd_inb(ahd_ddb_softc
, addr
);
1949 ahd_outb(ahd_ddb_softc
, addr
, new_value
);
1952 old_value
= ahd_inw(ahd_ddb_softc
, addr
);
1953 ahd_outw(ahd_ddb_softc
, addr
, new_value
);
1956 old_value
= ahd_inl(ahd_ddb_softc
, addr
);
1957 ahd_outl(ahd_ddb_softc
, addr
, new_value
);
1960 db_printf("%04lx (M)%x: \t0x%lx\t=\t0x%lx",
1961 (u_long
)addr
, ahd_inb(ahd_ddb_softc
, MODE_PTR
),
1962 (u_long
)old_value
, (u_long
)new_value
);
1971 DECLARE_MODULE(ahd
, ahd_mod
, SI_SUB_DRIVERS
, SI_ORDER_MIDDLE
);
1972 MODULE_DEPEND(ahd
, cam
, 1, 1, 1);
1973 MODULE_VERSION(ahd
, 1);