2 * Bus independent FreeBSD shim for the aic79xx based Adaptec SCSI controllers
4 * Copyright (c) 1994-2002, 2004 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#35 $
34 * $FreeBSD: src/sys/dev/aic7xxx/aic79xx_osm.c,v 1.23 2005/12/04 02:12:40 ru Exp $
35 * $DragonFly: src/sys/dev/disk/aic7xxx/aic79xx_osm.c,v 1.23 2008/02/10 00:01:02 pavalos Exp $
38 #include "aic79xx_osm.h"
39 #include "aic79xx_inline.h"
41 #include <sys/kthread.h>
48 #ifndef AHD_TMODE_ENABLE
49 #define AHD_TMODE_ENABLE 0
52 #include "aic_osm_lib.c"
54 #define ccb_scb_ptr spriv_ptr0
57 static void ahd_dump_targcmd(struct target_cmd
*cmd
);
59 static int ahd_modevent(module_t mod
, int type
, void *data
);
60 static void ahd_action(struct cam_sim
*sim
, union ccb
*ccb
);
61 static void ahd_set_tran_settings(struct ahd_softc
*ahd
,
62 int our_id
, char channel
,
63 struct ccb_trans_settings
*cts
);
64 static void ahd_get_tran_settings(struct ahd_softc
*ahd
,
65 int our_id
, char channel
,
66 struct ccb_trans_settings
*cts
);
67 static void ahd_async(void *callback_arg
, uint32_t code
,
68 struct cam_path
*path
, void *arg
);
69 static void ahd_execute_scb(void *arg
, bus_dma_segment_t
*dm_segs
,
70 int nsegments
, int error
);
71 static void ahd_poll(struct cam_sim
*sim
);
72 static void ahd_setup_data(struct ahd_softc
*ahd
, struct cam_sim
*sim
,
73 struct ccb_scsiio
*csio
, struct scb
*scb
);
74 static void ahd_abort_ccb(struct ahd_softc
*ahd
, struct cam_sim
*sim
,
76 static int ahd_create_path(struct ahd_softc
*ahd
,
77 char channel
, u_int target
, u_int lun
,
78 struct cam_path
**path
);
81 ahd_create_path(struct ahd_softc
*ahd
, char channel
, u_int target
,
82 u_int lun
, struct cam_path
**path
)
86 path_id
= cam_sim_path(ahd
->platform_data
->sim
);
87 return (xpt_create_path(path
, /*periph*/NULL
,
88 path_id
, target
, lun
));
92 ahd_map_int(struct ahd_softc
*ahd
)
96 /* Hook up our interrupt handler */
97 error
= bus_setup_intr(ahd
->dev_softc
, ahd
->platform_data
->irq
,
98 INTR_MPSAFE
, ahd_platform_intr
, ahd
,
99 &ahd
->platform_data
->ih
, NULL
);
101 device_printf(ahd
->dev_softc
, "bus_setup_intr() failed: %d\n",
107 * Attach all the sub-devices we can find
110 ahd_attach(struct ahd_softc
*ahd
)
113 struct ccb_setasync csa
;
115 struct cam_path
*path
;
122 * Create a thread to perform all recovery.
124 if (ahd_spawn_recovery_thread(ahd
) != 0)
127 ahd_controller_info(ahd
, ahd_info
);
128 kprintf("%s\n", ahd_info
);
132 * Construct our SIM entry
134 sim
= cam_sim_alloc(ahd_action
, ahd_poll
, "ahd", ahd
,
135 device_get_unit(ahd
->dev_softc
),
136 1, AHD_MAX_QUEUE
, NULL
);
140 if (xpt_bus_register(sim
, /*bus_id*/0) != CAM_SUCCESS
) {
146 if (xpt_create_path(&path
, /*periph*/NULL
,
147 cam_sim_path(sim
), CAM_TARGET_WILDCARD
,
148 CAM_LUN_WILDCARD
) != CAM_REQ_CMP
) {
149 xpt_bus_deregister(cam_sim_path(sim
));
155 xpt_setup_ccb(&csa
.ccb_h
, path
, /*priority*/5);
156 csa
.ccb_h
.func_code
= XPT_SASYNC_CB
;
157 csa
.event_enable
= AC_LOST_DEVICE
;
158 csa
.callback
= ahd_async
;
159 csa
.callback_arg
= sim
;
160 xpt_action((union ccb
*)&csa
);
164 ahd
->platform_data
->sim
= sim
;
165 ahd
->platform_data
->path
= path
;
168 /* We have to wait until after any system dumps... */
169 ahd
->platform_data
->eh
=
170 EVENTHANDLER_REGISTER(shutdown_post_sync
, ahd_shutdown
,
171 ahd
, SHUTDOWN_PRI_DRIVER
);
172 ahd_intr_enable(ahd
, TRUE
);
179 * Catch an interrupt from the adapter
182 ahd_platform_intr(void *arg
)
184 struct ahd_softc
*ahd
;
186 ahd
= (struct ahd_softc
*)arg
;
193 * We have an scb which has been processed by the
194 * adaptor, now we look to see how the operation
198 ahd_done(struct ahd_softc
*ahd
, struct scb
*scb
)
202 CAM_DEBUG(scb
->io_ctx
->ccb_h
.path
, CAM_DEBUG_TRACE
,
203 ("ahd_done - scb %d\n", SCB_GET_TAG(scb
)));
206 LIST_REMOVE(scb
, pending_links
);
207 if ((scb
->flags
& SCB_TIMEDOUT
) != 0)
208 LIST_REMOVE(scb
, timedout_links
);
210 callout_stop(&scb
->io_timer
);
212 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
215 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
216 op
= BUS_DMASYNC_POSTREAD
;
218 op
= BUS_DMASYNC_POSTWRITE
;
219 bus_dmamap_sync(ahd
->buffer_dmat
, scb
->dmamap
, op
);
220 bus_dmamap_unload(ahd
->buffer_dmat
, scb
->dmamap
);
223 #ifdef AHD_TARGET_MODE
224 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
225 struct cam_path
*ccb_path
;
228 * If we have finally disconnected, clean up our
229 * pending device state.
230 * XXX - There may be error states that cause where
231 * we will remain connected.
233 ccb_path
= ccb
->ccb_h
.path
;
234 if (ahd
->pending_device
!= NULL
235 && xpt_path_comp(ahd
->pending_device
->path
, ccb_path
) == 0) {
237 if ((ccb
->ccb_h
.flags
& CAM_SEND_STATUS
) != 0) {
238 ahd
->pending_device
= NULL
;
240 xpt_print_path(ccb
->ccb_h
.path
);
241 kprintf("Still disconnected\n");
246 if (aic_get_transaction_status(scb
) == CAM_REQ_INPROG
)
247 ccb
->ccb_h
.status
|= CAM_REQ_CMP
;
248 ccb
->ccb_h
.status
&= ~CAM_SIM_QUEUED
;
249 ahd_free_scb(ahd
, scb
);
255 if ((scb
->flags
& SCB_RECOVERY_SCB
) != 0) {
256 struct scb
*list_scb
;
258 ahd
->scb_data
.recovery_scbs
--;
260 if (aic_get_transaction_status(scb
) == CAM_BDR_SENT
261 || aic_get_transaction_status(scb
) == CAM_REQ_ABORTED
)
262 aic_set_transaction_status(scb
, CAM_CMD_TIMEOUT
);
264 if (ahd
->scb_data
.recovery_scbs
== 0) {
266 * All recovery actions have completed successfully,
267 * so reinstate the timeouts for all other pending
270 LIST_FOREACH(list_scb
,
271 &ahd
->pending_scbs
, pending_links
) {
273 aic_scb_timer_reset(list_scb
,
274 aic_get_timeout(scb
));
277 ahd_print_path(ahd
, scb
);
278 kprintf("no longer in timeout, status = %x\n",
283 /* Don't clobber any existing error state */
284 if (aic_get_transaction_status(scb
) == CAM_REQ_INPROG
) {
285 ccb
->ccb_h
.status
|= CAM_REQ_CMP
;
286 } else if ((scb
->flags
& SCB_SENSE
) != 0) {
288 * We performed autosense retrieval.
290 * Zero any sense not transferred by the
291 * device. The SCSI spec mandates that any
292 * untransfered data should be assumed to be
293 * zero. Complete the 'bounce' of sense information
294 * through buffers accessible via bus-space by
295 * copying it into the clients csio.
297 memset(&ccb
->csio
.sense_data
, 0, sizeof(ccb
->csio
.sense_data
));
298 memcpy(&ccb
->csio
.sense_data
,
299 ahd_get_sense_buf(ahd
, scb
),
300 /* XXX What size do we want to use??? */
301 sizeof(ccb
->csio
.sense_data
)
302 - ccb
->csio
.sense_resid
);
303 scb
->io_ctx
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
304 } else if ((scb
->flags
& SCB_PKT_SENSE
) != 0) {
305 struct scsi_status_iu_header
*siu
;
310 * Copy only the sense data into the provided buffer.
312 siu
= (struct scsi_status_iu_header
*)scb
->sense_data
;
313 sense_len
= MIN(scsi_4btoul(siu
->sense_length
),
314 sizeof(ccb
->csio
.sense_data
));
315 memset(&ccb
->csio
.sense_data
, 0, sizeof(ccb
->csio
.sense_data
));
316 memcpy(&ccb
->csio
.sense_data
,
317 ahd_get_sense_buf(ahd
, scb
) + SIU_SENSE_OFFSET(siu
),
319 kprintf("Copied %d bytes of sense data offset %d:", sense_len
,
320 SIU_SENSE_OFFSET(siu
));
321 for (i
= 0; i
< sense_len
; i
++)
322 kprintf(" 0x%x", ((uint8_t *)&ccb
->csio
.sense_data
)[i
]);
324 scb
->io_ctx
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
326 ccb
->ccb_h
.status
&= ~CAM_SIM_QUEUED
;
327 ahd_free_scb(ahd
, scb
);
332 ahd_action(struct cam_sim
*sim
, union ccb
*ccb
)
334 struct ahd_softc
*ahd
;
335 #ifdef AHD_TARGET_MODE
336 struct ahd_tmode_lstate
*lstate
;
341 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
, ("ahd_action\n"));
343 ahd
= (struct ahd_softc
*)cam_sim_softc(sim
);
345 target_id
= ccb
->ccb_h
.target_id
;
346 our_id
= SIM_SCSI_ID(ahd
, sim
);
348 switch (ccb
->ccb_h
.func_code
) {
349 /* Common cases first */
350 #ifdef AHD_TARGET_MODE
351 case XPT_ACCEPT_TARGET_IO
: /* Accept Host Target Mode CDB */
352 case XPT_CONT_TARGET_IO
:/* Continue Host Target I/O Connection*/
354 struct ahd_tmode_tstate
*tstate
;
357 status
= ahd_find_tmode_devs(ahd
, sim
, ccb
, &tstate
,
360 if (status
!= CAM_REQ_CMP
) {
361 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
362 /* Response from the black hole device */
364 lstate
= ahd
->black_hole
;
366 ccb
->ccb_h
.status
= status
;
371 if (ccb
->ccb_h
.func_code
== XPT_ACCEPT_TARGET_IO
) {
373 SLIST_INSERT_HEAD(&lstate
->accept_tios
, &ccb
->ccb_h
,
375 ccb
->ccb_h
.status
= CAM_REQ_INPROG
;
376 if ((ahd
->flags
& AHD_TQINFIFO_BLOCKED
) != 0)
377 ahd_run_tqinfifo(ahd
, /*paused*/FALSE
);
382 * The target_id represents the target we attempt to
383 * select. In target mode, this is the initiator of
384 * the original command.
387 target_id
= ccb
->csio
.init_id
;
391 case XPT_SCSI_IO
: /* Execute the requested I/O operation */
392 case XPT_RESET_DEV
: /* Bus Device Reset the specified SCSI device */
395 struct hardware_scb
*hscb
;
396 struct ahd_initiator_tinfo
*tinfo
;
397 struct ahd_tmode_tstate
*tstate
;
400 if ((ahd
->flags
& AHD_INITIATORROLE
) == 0
401 && (ccb
->ccb_h
.func_code
== XPT_SCSI_IO
402 || ccb
->ccb_h
.func_code
== XPT_RESET_DEV
)) {
403 ccb
->ccb_h
.status
= CAM_PROVIDE_FAIL
;
411 tinfo
= ahd_fetch_transinfo(ahd
, 'A', our_id
,
413 if ((ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
) == 0
414 || (tinfo
->curr
.ppr_options
& MSG_EXT_PPR_IU_REQ
) != 0
415 || ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
416 col_idx
= AHD_NEVER_COL_IDX
;
418 col_idx
= AHD_BUILD_COL_IDX(target_id
,
419 ccb
->ccb_h
.target_lun
);
421 if ((scb
= ahd_get_scb(ahd
, col_idx
)) == NULL
) {
423 xpt_freeze_simq(sim
, /*count*/1);
424 ahd
->flags
|= AHD_RESOURCE_SHORTAGE
;
425 ccb
->ccb_h
.status
= CAM_REQUEUE_REQ
;
432 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_SUBTRACE
,
433 ("start scb(%p)\n", scb
));
436 * So we can find the SCB when an abort is requested
438 ccb
->ccb_h
.ccb_scb_ptr
= scb
;
441 * Put all the arguments for the xfer in the scb
444 hscb
->scsiid
= BUILD_SCSIID(ahd
, sim
, target_id
, our_id
);
445 hscb
->lun
= ccb
->ccb_h
.target_lun
;
446 if (ccb
->ccb_h
.func_code
== XPT_RESET_DEV
) {
448 scb
->flags
|= SCB_DEVICE_RESET
;
449 hscb
->control
|= MK_MESSAGE
;
450 hscb
->task_management
= SIU_TASKMGMT_LUN_RESET
;
451 ahd_execute_scb(scb
, NULL
, 0, 0);
453 #ifdef AHD_TARGET_MODE
454 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
455 struct target_data
*tdata
;
457 tdata
= &hscb
->shared_data
.tdata
;
458 if (ahd
->pending_device
== lstate
)
459 scb
->flags
|= SCB_TARGET_IMMEDIATE
;
460 hscb
->control
|= TARGET_SCB
;
461 tdata
->target_phases
= 0;
462 if ((ccb
->ccb_h
.flags
& CAM_SEND_STATUS
) != 0) {
463 tdata
->target_phases
|= SPHASE_PENDING
;
465 ccb
->csio
.scsi_status
;
467 if (ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
)
468 tdata
->target_phases
|= NO_DISCONNECT
;
470 tdata
->initiator_tag
=
471 ahd_htole16(ccb
->csio
.tag_id
);
474 hscb
->task_management
= 0;
475 if (ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
)
476 hscb
->control
|= ccb
->csio
.tag_action
;
478 ahd_setup_data(ahd
, sim
, &ccb
->csio
, scb
);
482 #ifdef AHD_TARGET_MODE
484 case XPT_IMMED_NOTIFY
:
486 struct ahd_tmode_tstate
*tstate
;
487 struct ahd_tmode_lstate
*lstate
;
490 status
= ahd_find_tmode_devs(ahd
, sim
, ccb
, &tstate
,
493 if (status
!= CAM_REQ_CMP
) {
494 ccb
->ccb_h
.status
= status
;
498 SLIST_INSERT_HEAD(&lstate
->immed_notifies
, &ccb
->ccb_h
,
500 ccb
->ccb_h
.status
= CAM_REQ_INPROG
;
501 ahd_send_lstate_events(ahd
, lstate
);
504 case XPT_EN_LUN
: /* Enable LUN as a target */
505 ahd_handle_en_lun(ahd
, sim
, ccb
);
509 case XPT_ABORT
: /* Abort the specified CCB */
511 ahd_abort_ccb(ahd
, sim
, ccb
);
514 case XPT_SET_TRAN_SETTINGS
:
516 ahd_set_tran_settings(ahd
, SIM_SCSI_ID(ahd
, sim
),
517 SIM_CHANNEL(ahd
, sim
), &ccb
->cts
);
521 case XPT_GET_TRAN_SETTINGS
:
522 /* Get default/user set transfer settings for the target */
524 ahd_get_tran_settings(ahd
, SIM_SCSI_ID(ahd
, sim
),
525 SIM_CHANNEL(ahd
, sim
), &ccb
->cts
);
529 case XPT_CALC_GEOMETRY
:
531 cam_calc_geometry(&ccb
->ccg
, ahd
->flags
& AHD_EXTENDED_TRANS_A
);
535 case XPT_RESET_BUS
: /* Reset the specified SCSI bus */
539 found
= ahd_reset_channel(ahd
, SIM_CHANNEL(ahd
, sim
),
540 /*initiate reset*/TRUE
);
542 xpt_print_path(SIM_PATH(ahd
, sim
));
543 kprintf("SCSI bus reset delivered. "
544 "%d SCBs aborted.\n", found
);
546 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
550 case XPT_TERM_IO
: /* Terminate the I/O process */
552 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
555 case XPT_PATH_INQ
: /* Path routing inquiry */
557 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
559 cpi
->version_num
= 1; /* XXX??? */
560 cpi
->hba_inquiry
= PI_SDTR_ABLE
|PI_TAG_ABLE
;
561 if ((ahd
->features
& AHD_WIDE
) != 0)
562 cpi
->hba_inquiry
|= PI_WIDE_16
;
563 if ((ahd
->features
& AHD_TARGETMODE
) != 0) {
564 cpi
->target_sprt
= PIT_PROCESSOR
568 cpi
->target_sprt
= 0;
571 cpi
->hba_eng_cnt
= 0;
572 cpi
->max_target
= (ahd
->features
& AHD_WIDE
) ? 15 : 7;
573 cpi
->max_lun
= AHD_NUM_LUNS_NONPKT
- 1;
574 cpi
->initiator_id
= ahd
->our_id
;
575 if ((ahd
->flags
& AHD_RESET_BUS_A
) == 0) {
576 cpi
->hba_misc
|= PIM_NOBUSRESET
;
578 cpi
->bus_id
= cam_sim_bus(sim
);
579 cpi
->base_transfer_speed
= 3300;
580 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
581 strncpy(cpi
->hba_vid
, "Adaptec", HBA_IDLEN
);
582 strncpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
583 cpi
->unit_number
= cam_sim_unit(sim
);
584 cpi
->protocol
= PROTO_SCSI
;
585 cpi
->protocol_version
= SCSI_REV_2
;
586 cpi
->transport
= XPORT_SPI
;
587 cpi
->transport_version
= 2;
588 cpi
->xport_specific
.spi
.ppr_options
= SID_SPI_CLOCK_ST
;
589 cpi
->transport_version
= 4;
590 cpi
->xport_specific
.spi
.ppr_options
= SID_SPI_CLOCK_DT_ST
;
591 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
596 ccb
->ccb_h
.status
= CAM_PROVIDE_FAIL
;
604 ahd_set_tran_settings(struct ahd_softc
*ahd
, int our_id
, char channel
,
605 struct ccb_trans_settings
*cts
)
607 struct ahd_devinfo devinfo
;
608 struct ccb_trans_settings_scsi
*scsi
;
609 struct ccb_trans_settings_spi
*spi
;
610 struct ahd_initiator_tinfo
*tinfo
;
611 struct ahd_tmode_tstate
*tstate
;
612 uint16_t *discenable
;
616 scsi
= &cts
->proto_specific
.scsi
;
617 spi
= &cts
->xport_specific
.spi
;
618 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
619 cts
->ccb_h
.target_id
,
620 cts
->ccb_h
.target_lun
,
621 SIM_CHANNEL(ahd
, sim
),
623 tinfo
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
625 devinfo
.target
, &tstate
);
627 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
) {
628 update_type
|= AHD_TRANS_GOAL
;
629 discenable
= &tstate
->discenable
;
630 tagenable
= &tstate
->tagenable
;
631 tinfo
->curr
.protocol_version
= cts
->protocol_version
;
632 tinfo
->curr
.transport_version
= cts
->transport_version
;
633 tinfo
->goal
.protocol_version
= cts
->protocol_version
;
634 tinfo
->goal
.transport_version
= cts
->transport_version
;
635 } else if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
636 update_type
|= AHD_TRANS_USER
;
637 discenable
= &ahd
->user_discenable
;
638 tagenable
= &ahd
->user_tagenable
;
639 tinfo
->user
.protocol_version
= cts
->protocol_version
;
640 tinfo
->user
.transport_version
= cts
->transport_version
;
642 cts
->ccb_h
.status
= CAM_REQ_INVALID
;
646 if ((spi
->valid
& CTS_SPI_VALID_DISC
) != 0) {
647 if ((spi
->flags
& CTS_SPI_FLAGS_DISC_ENB
) != 0)
648 *discenable
|= devinfo
.target_mask
;
650 *discenable
&= ~devinfo
.target_mask
;
653 if ((scsi
->valid
& CTS_SCSI_VALID_TQ
) != 0) {
654 if ((scsi
->flags
& CTS_SCSI_FLAGS_TAG_ENB
) != 0)
655 *tagenable
|= devinfo
.target_mask
;
657 *tagenable
&= ~devinfo
.target_mask
;
660 if ((spi
->valid
& CTS_SPI_VALID_BUS_WIDTH
) != 0) {
661 ahd_validate_width(ahd
, /*tinfo limit*/NULL
,
662 &spi
->bus_width
, ROLE_UNKNOWN
);
663 ahd_set_width(ahd
, &devinfo
, spi
->bus_width
,
664 update_type
, /*paused*/FALSE
);
667 if ((spi
->valid
& CTS_SPI_VALID_PPR_OPTIONS
) == 0) {
668 if (update_type
== AHD_TRANS_USER
)
669 spi
->ppr_options
= tinfo
->user
.ppr_options
;
671 spi
->ppr_options
= tinfo
->goal
.ppr_options
;
674 if ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) == 0) {
675 if (update_type
== AHD_TRANS_USER
)
676 spi
->sync_offset
= tinfo
->user
.offset
;
678 spi
->sync_offset
= tinfo
->goal
.offset
;
681 if ((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) == 0) {
682 if (update_type
== AHD_TRANS_USER
)
683 spi
->sync_period
= tinfo
->user
.period
;
685 spi
->sync_period
= tinfo
->goal
.period
;
688 if (((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) != 0)
689 || ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) != 0)) {
692 maxsync
= AHD_SYNCRATE_MAX
;
694 if (spi
->bus_width
!= MSG_EXT_WDTR_BUS_16_BIT
)
695 spi
->ppr_options
&= ~MSG_EXT_PPR_DT_REQ
;
697 if ((*discenable
& devinfo
.target_mask
) == 0)
698 spi
->ppr_options
&= ~MSG_EXT_PPR_IU_REQ
;
700 ahd_find_syncrate(ahd
, &spi
->sync_period
,
701 &spi
->ppr_options
, maxsync
);
702 ahd_validate_offset(ahd
, /*tinfo limit*/NULL
,
703 spi
->sync_period
, &spi
->sync_offset
,
704 spi
->bus_width
, ROLE_UNKNOWN
);
706 /* We use a period of 0 to represent async */
707 if (spi
->sync_offset
== 0) {
708 spi
->sync_period
= 0;
709 spi
->ppr_options
= 0;
712 ahd_set_syncrate(ahd
, &devinfo
, spi
->sync_period
,
713 spi
->sync_offset
, spi
->ppr_options
,
714 update_type
, /*paused*/FALSE
);
716 cts
->ccb_h
.status
= CAM_REQ_CMP
;
720 ahd_get_tran_settings(struct ahd_softc
*ahd
, int our_id
, char channel
,
721 struct ccb_trans_settings
*cts
)
723 struct ahd_devinfo devinfo
;
724 struct ccb_trans_settings_scsi
*scsi
;
725 struct ccb_trans_settings_spi
*spi
;
726 struct ahd_initiator_tinfo
*targ_info
;
727 struct ahd_tmode_tstate
*tstate
;
728 struct ahd_transinfo
*tinfo
;
730 scsi
= &cts
->proto_specific
.scsi
;
731 spi
= &cts
->xport_specific
.spi
;
732 ahd_compile_devinfo(&devinfo
, our_id
,
733 cts
->ccb_h
.target_id
,
734 cts
->ccb_h
.target_lun
,
735 channel
, ROLE_UNKNOWN
);
736 targ_info
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
738 devinfo
.target
, &tstate
);
740 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
)
741 tinfo
= &targ_info
->curr
;
743 tinfo
= &targ_info
->user
;
745 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
746 spi
->flags
&= ~CTS_SPI_FLAGS_DISC_ENB
;
747 if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
748 if ((ahd
->user_discenable
& devinfo
.target_mask
) != 0)
749 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
751 if ((ahd
->user_tagenable
& devinfo
.target_mask
) != 0)
752 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
754 if ((tstate
->discenable
& devinfo
.target_mask
) != 0)
755 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
757 if ((tstate
->tagenable
& devinfo
.target_mask
) != 0)
758 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
760 cts
->protocol_version
= tinfo
->protocol_version
;
761 cts
->transport_version
= tinfo
->transport_version
;
763 spi
->sync_period
= tinfo
->period
;
764 spi
->sync_offset
= tinfo
->offset
;
765 spi
->bus_width
= tinfo
->width
;
766 spi
->ppr_options
= tinfo
->ppr_options
;
768 cts
->protocol
= PROTO_SCSI
;
769 cts
->transport
= XPORT_SPI
;
770 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
771 | CTS_SPI_VALID_SYNC_OFFSET
772 | CTS_SPI_VALID_BUS_WIDTH
773 | CTS_SPI_VALID_PPR_OPTIONS
;
775 if (cts
->ccb_h
.target_lun
!= CAM_LUN_WILDCARD
) {
776 scsi
->valid
= CTS_SCSI_VALID_TQ
;
777 spi
->valid
|= CTS_SPI_VALID_DISC
;
782 cts
->ccb_h
.status
= CAM_REQ_CMP
;
786 ahd_async(void *callback_arg
, uint32_t code
, struct cam_path
*path
, void *arg
)
788 struct ahd_softc
*ahd
;
791 sim
= (struct cam_sim
*)callback_arg
;
792 ahd
= (struct ahd_softc
*)cam_sim_softc(sim
);
796 struct ahd_devinfo devinfo
;
798 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
799 xpt_path_target_id(path
),
800 xpt_path_lun_id(path
),
801 SIM_CHANNEL(ahd
, sim
),
805 * Revert to async/narrow transfers
806 * for the next device.
808 ahd_set_width(ahd
, &devinfo
, MSG_EXT_WDTR_BUS_8_BIT
,
809 AHD_TRANS_GOAL
|AHD_TRANS_CUR
, /*paused*/FALSE
);
810 ahd_set_syncrate(ahd
, &devinfo
, /*period*/0, /*offset*/0,
811 /*ppr_options*/0, AHD_TRANS_GOAL
|AHD_TRANS_CUR
,
821 ahd_execute_scb(void *arg
, bus_dma_segment_t
*dm_segs
, int nsegments
,
826 struct ahd_softc
*ahd
;
827 struct ahd_initiator_tinfo
*tinfo
;
828 struct ahd_tmode_tstate
*tstate
;
831 scb
= (struct scb
*)arg
;
833 ahd
= scb
->ahd_softc
;
837 aic_set_transaction_status(scb
, CAM_REQ_TOO_BIG
);
839 aic_set_transaction_status(scb
, CAM_REQ_CMP_ERR
);
841 bus_dmamap_unload(ahd
->buffer_dmat
, scb
->dmamap
);
842 ahd_free_scb(ahd
, scb
);
847 if (nsegments
!= 0) {
852 /* Copy the segments into our SG list */
853 for (i
= nsegments
, sg
= scb
->sg_list
; i
> 0; i
--) {
855 sg
= ahd_sg_setup(ahd
, scb
, sg
, dm_segs
->ds_addr
,
861 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
862 op
= BUS_DMASYNC_PREREAD
;
864 op
= BUS_DMASYNC_PREWRITE
;
866 bus_dmamap_sync(ahd
->buffer_dmat
, scb
->dmamap
, op
);
868 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
869 struct target_data
*tdata
;
871 tdata
= &scb
->hscb
->shared_data
.tdata
;
872 tdata
->target_phases
|= DPHASE_PENDING
;
873 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_OUT
)
874 tdata
->data_phase
= P_DATAOUT
;
876 tdata
->data_phase
= P_DATAIN
;
881 * Last time we need to check if this SCB needs to
884 if (aic_get_transaction_status(scb
) != CAM_REQ_INPROG
) {
886 bus_dmamap_unload(ahd
->buffer_dmat
,
888 ahd_free_scb(ahd
, scb
);
893 tinfo
= ahd_fetch_transinfo(ahd
, SCSIID_CHANNEL(ahd
, scb
->hscb
->scsiid
),
894 SCSIID_OUR_ID(scb
->hscb
->scsiid
),
895 SCSIID_TARGET(ahd
, scb
->hscb
->scsiid
),
898 mask
= SCB_GET_TARGET_MASK(ahd
, scb
);
900 if ((tstate
->discenable
& mask
) != 0
901 && (ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
) == 0)
902 scb
->hscb
->control
|= DISCENB
;
904 if ((tinfo
->curr
.ppr_options
& MSG_EXT_PPR_IU_REQ
) != 0) {
905 scb
->flags
|= SCB_PACKETIZED
;
906 if (scb
->hscb
->task_management
!= 0)
907 scb
->hscb
->control
&= ~MK_MESSAGE
;
910 if ((ccb
->ccb_h
.flags
& CAM_NEGOTIATE
) != 0
911 && (tinfo
->goal
.width
!= 0
912 || tinfo
->goal
.period
!= 0
913 || tinfo
->goal
.ppr_options
!= 0)) {
914 scb
->flags
|= SCB_NEGOTIATE
;
915 scb
->hscb
->control
|= MK_MESSAGE
;
916 } else if ((tstate
->auto_negotiate
& mask
) != 0) {
917 scb
->flags
|= SCB_AUTO_NEGOTIATE
;
918 scb
->hscb
->control
|= MK_MESSAGE
;
921 LIST_INSERT_HEAD(&ahd
->pending_scbs
, scb
, pending_links
);
923 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
925 aic_scb_timer_start(scb
);
927 if ((scb
->flags
& SCB_TARGET_IMMEDIATE
) != 0) {
928 /* Define a mapping from our tag to the SCB. */
929 ahd
->scb_data
.scbindex
[SCB_GET_TAG(scb
)] = scb
;
931 ahd_set_scbptr(ahd
, SCB_GET_TAG(scb
));
932 ahd_outb(ahd
, RETURN_1
, CONT_MSG_LOOP_TARG
);
935 ahd_queue_scb(ahd
, scb
);
940 ahd_poll(struct cam_sim
*sim
)
942 ahd_intr(cam_sim_softc(sim
));
946 ahd_setup_data(struct ahd_softc
*ahd
, struct cam_sim
*sim
,
947 struct ccb_scsiio
*csio
, struct scb
*scb
)
949 struct hardware_scb
*hscb
;
950 struct ccb_hdr
*ccb_h
;
953 ccb_h
= &csio
->ccb_h
;
956 csio
->sense_resid
= 0;
957 if (ccb_h
->func_code
== XPT_SCSI_IO
) {
958 hscb
->cdb_len
= csio
->cdb_len
;
959 if ((ccb_h
->flags
& CAM_CDB_POINTER
) != 0) {
961 if (hscb
->cdb_len
> MAX_CDB_LEN
962 && (ccb_h
->flags
& CAM_CDB_PHYS
) == 0) {
965 * Should CAM start to support CDB sizes
966 * greater than 16 bytes, we could use
967 * the sense buffer to store the CDB.
969 aic_set_transaction_status(scb
,
971 ahd_free_scb(ahd
, scb
);
972 xpt_done((union ccb
*)csio
);
975 if ((ccb_h
->flags
& CAM_CDB_PHYS
) != 0) {
976 hscb
->shared_data
.idata
.cdb_from_host
.cdbptr
=
977 aic_htole64((uintptr_t)csio
->cdb_io
.cdb_ptr
);
978 hscb
->shared_data
.idata
.cdb_from_host
.cdblen
=
980 hscb
->cdb_len
|= SCB_CDB_LEN_PTR
;
982 memcpy(hscb
->shared_data
.idata
.cdb
,
983 csio
->cdb_io
.cdb_ptr
,
987 if (hscb
->cdb_len
> MAX_CDB_LEN
) {
989 aic_set_transaction_status(scb
,
991 ahd_free_scb(ahd
, scb
);
992 xpt_done((union ccb
*)csio
);
995 memcpy(hscb
->shared_data
.idata
.cdb
,
996 csio
->cdb_io
.cdb_bytes
, hscb
->cdb_len
);
1000 /* Only use S/G if there is a transfer */
1001 if ((ccb_h
->flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
1002 if ((ccb_h
->flags
& CAM_SCATTER_VALID
) == 0) {
1003 /* We've been given a pointer to a single buffer */
1004 if ((ccb_h
->flags
& CAM_DATA_PHYS
) == 0) {
1008 error
= bus_dmamap_load(ahd
->buffer_dmat
,
1014 if (error
== EINPROGRESS
) {
1016 * So as to maintain ordering,
1017 * freeze the controller queue
1018 * until our mapping is
1021 xpt_freeze_simq(sim
,
1023 scb
->io_ctx
->ccb_h
.status
|=
1028 struct bus_dma_segment seg
;
1030 /* Pointer to physical buffer */
1031 if (csio
->dxfer_len
> AHD_MAXTRANSFER_SIZE
)
1032 panic("ahd_setup_data - Transfer size "
1033 "larger than can device max");
1036 (bus_addr_t
)(vm_offset_t
)csio
->data_ptr
;
1037 seg
.ds_len
= csio
->dxfer_len
;
1038 ahd_execute_scb(scb
, &seg
, 1, 0);
1041 struct bus_dma_segment
*segs
;
1043 if ((ccb_h
->flags
& CAM_DATA_PHYS
) != 0)
1044 panic("ahd_setup_data - Physical segment "
1045 "pointers unsupported");
1047 if ((ccb_h
->flags
& CAM_SG_LIST_PHYS
) == 0)
1048 panic("ahd_setup_data - Virtual segment "
1049 "addresses unsupported");
1051 /* Just use the segments provided */
1052 segs
= (struct bus_dma_segment
*)csio
->data_ptr
;
1053 ahd_execute_scb(scb
, segs
, csio
->sglist_cnt
, 0);
1056 ahd_execute_scb(scb
, NULL
, 0, 0);
1061 ahd_abort_ccb(struct ahd_softc
*ahd
, struct cam_sim
*sim
, union ccb
*ccb
)
1063 union ccb
*abort_ccb
;
1065 abort_ccb
= ccb
->cab
.abort_ccb
;
1066 switch (abort_ccb
->ccb_h
.func_code
) {
1067 #ifdef AHD_TARGET_MODE
1068 case XPT_ACCEPT_TARGET_IO
:
1069 case XPT_IMMED_NOTIFY
:
1070 case XPT_CONT_TARGET_IO
:
1072 struct ahd_tmode_tstate
*tstate
;
1073 struct ahd_tmode_lstate
*lstate
;
1074 struct ccb_hdr_slist
*list
;
1077 status
= ahd_find_tmode_devs(ahd
, sim
, abort_ccb
, &tstate
,
1080 if (status
!= CAM_REQ_CMP
) {
1081 ccb
->ccb_h
.status
= status
;
1085 if (abort_ccb
->ccb_h
.func_code
== XPT_ACCEPT_TARGET_IO
)
1086 list
= &lstate
->accept_tios
;
1087 else if (abort_ccb
->ccb_h
.func_code
== XPT_IMMED_NOTIFY
)
1088 list
= &lstate
->immed_notifies
;
1093 struct ccb_hdr
*curelm
;
1096 curelm
= SLIST_FIRST(list
);
1098 if (curelm
== &abort_ccb
->ccb_h
) {
1100 SLIST_REMOVE_HEAD(list
, sim_links
.sle
);
1102 while(curelm
!= NULL
) {
1103 struct ccb_hdr
*nextelm
;
1106 SLIST_NEXT(curelm
, sim_links
.sle
);
1108 if (nextelm
== &abort_ccb
->ccb_h
) {
1121 abort_ccb
->ccb_h
.status
= CAM_REQ_ABORTED
;
1122 xpt_done(abort_ccb
);
1123 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1125 xpt_print_path(abort_ccb
->ccb_h
.path
);
1126 kprintf("Not found\n");
1127 ccb
->ccb_h
.status
= CAM_PATH_INVALID
;
1135 /* XXX Fully implement the hard ones */
1136 ccb
->ccb_h
.status
= CAM_UA_ABORT
;
1139 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1146 ahd_send_async(struct ahd_softc
*ahd
, char channel
, u_int target
,
1147 u_int lun
, ac_code code
, void *opt_arg
)
1149 struct ccb_trans_settings cts
;
1150 struct cam_path
*path
;
1155 error
= ahd_create_path(ahd
, channel
, target
, lun
, &path
);
1157 if (error
!= CAM_REQ_CMP
)
1161 case AC_TRANSFER_NEG
:
1163 struct ccb_trans_settings_scsi
*scsi
;
1165 cts
.type
= CTS_TYPE_CURRENT_SETTINGS
;
1166 scsi
= &cts
.proto_specific
.scsi
;
1167 cts
.ccb_h
.path
= path
;
1168 cts
.ccb_h
.target_id
= target
;
1169 cts
.ccb_h
.target_lun
= lun
;
1170 ahd_get_tran_settings(ahd
, ahd
->our_id
, channel
, &cts
);
1172 scsi
->valid
&= ~CTS_SCSI_VALID_TQ
;
1173 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
1174 if (opt_arg
== NULL
)
1176 if (*((ahd_queue_alg
*)opt_arg
) == AHD_QUEUE_TAGGED
)
1177 scsi
->flags
|= ~CTS_SCSI_FLAGS_TAG_ENB
;
1178 scsi
->valid
|= CTS_SCSI_VALID_TQ
;
1185 panic("ahd_send_async: Unexpected async event");
1187 xpt_async(code
, path
, arg
);
1188 xpt_free_path(path
);
1192 ahd_platform_set_tags(struct ahd_softc
*ahd
,
1193 struct ahd_devinfo
*devinfo
, int enable
)
1198 ahd_platform_alloc(struct ahd_softc
*ahd
, void *platform_arg
)
1200 ahd
->platform_data
= kmalloc(sizeof(struct ahd_platform_data
), M_DEVBUF
,
1201 M_INTWAIT
| M_ZERO
);
1206 ahd_platform_free(struct ahd_softc
*ahd
)
1208 struct ahd_platform_data
*pdata
;
1210 pdata
= ahd
->platform_data
;
1211 if (pdata
!= NULL
) {
1212 if (pdata
->regs
[0] != NULL
)
1213 bus_release_resource(ahd
->dev_softc
,
1214 pdata
->regs_res_type
[0],
1215 pdata
->regs_res_id
[0],
1218 if (pdata
->regs
[1] != NULL
)
1219 bus_release_resource(ahd
->dev_softc
,
1220 pdata
->regs_res_type
[1],
1221 pdata
->regs_res_id
[1],
1224 if (pdata
->irq
!= NULL
)
1225 bus_release_resource(ahd
->dev_softc
,
1226 pdata
->irq_res_type
,
1229 if (pdata
->sim
!= NULL
) {
1230 xpt_async(AC_LOST_DEVICE
, pdata
->path
, NULL
);
1231 xpt_free_path(pdata
->path
);
1232 xpt_bus_deregister(cam_sim_path(pdata
->sim
));
1233 cam_sim_free(pdata
->sim
);
1235 if (pdata
->eh
!= NULL
)
1236 EVENTHANDLER_DEREGISTER(shutdown_post_sync
, pdata
->eh
);
1237 kfree(ahd
->platform_data
, M_DEVBUF
);
1242 ahd_softc_comp(struct ahd_softc
*lahd
, struct ahd_softc
*rahd
)
1244 /* We don't sort softcs under FreeBSD so report equal always */
1249 ahd_detach(device_t dev
)
1251 struct ahd_softc
*ahd
;
1253 device_printf(dev
, "detaching device\n");
1254 ahd
= device_get_softc(dev
);
1256 TAILQ_REMOVE(&ahd_tailq
, ahd
, links
);
1257 ahd_intr_enable(ahd
, FALSE
);
1258 bus_teardown_intr(dev
, ahd
->platform_data
->irq
, ahd
->platform_data
->ih
);
1266 ahd_dump_targcmd(struct target_cmd
*cmd
)
1272 byte
= &cmd
->initiator_channel
;
1273 /* Debugging info for received commands */
1274 last_byte
= &cmd
[1].initiator_channel
;
1277 while (byte
< last_byte
) {
1280 kprintf("%#x", *byte
++);
1293 ahd_modevent(module_t mod
, int type
, void *data
)
1295 /* XXX Deal with busy status on unload. */
1296 /* XXX Deal with unknown events */
1300 static moduledata_t ahd_mod
= {
1306 /********************************** DDB Hooks *********************************/
1308 static struct ahd_softc
*ahd_ddb_softc
;
1309 static int ahd_ddb_paused
;
1310 static int ahd_ddb_paused_on_entry
;
1311 DB_COMMAND(ahd_sunit
, ahd_ddb_sunit
)
1313 struct ahd_softc
*list_ahd
;
1315 ahd_ddb_softc
= NULL
;
1316 TAILQ_FOREACH(list_ahd
, &ahd_tailq
, links
) {
1317 if (list_ahd
->unit
== addr
)
1318 ahd_ddb_softc
= list_ahd
;
1320 if (ahd_ddb_softc
== NULL
)
1321 db_error("No matching softc found!\n");
1324 DB_COMMAND(ahd_pause
, ahd_ddb_pause
)
1326 if (ahd_ddb_softc
== NULL
) {
1327 db_error("Must set unit with ahd_sunit first!\n");
1330 if (ahd_ddb_paused
== 0) {
1332 if (ahd_is_paused(ahd_ddb_softc
)) {
1333 ahd_ddb_paused_on_entry
++;
1336 ahd_pause(ahd_ddb_softc
);
1340 DB_COMMAND(ahd_unpause
, ahd_ddb_unpause
)
1342 if (ahd_ddb_softc
== NULL
) {
1343 db_error("Must set unit with ahd_sunit first!\n");
1346 if (ahd_ddb_paused
!= 0) {
1348 if (ahd_ddb_paused_on_entry
)
1350 ahd_unpause(ahd_ddb_softc
);
1351 } else if (ahd_ddb_paused_on_entry
!= 0) {
1352 /* Two unpauses to clear a paused on entry. */
1353 ahd_ddb_paused_on_entry
= 0;
1354 ahd_unpause(ahd_ddb_softc
);
1358 DB_COMMAND(ahd_in
, ahd_ddb_in
)
1363 if (ahd_ddb_softc
== NULL
) {
1364 db_error("Must set unit with ahd_sunit first!\n");
1371 while ((c
= *modif
++) != '\0') {
1387 while (--count
>= 0) {
1388 db_printf("%04lx (M)%x: \t", (u_long
)addr
,
1389 ahd_inb(ahd_ddb_softc
, MODE_PTR
));
1392 db_printf("%02x\n", ahd_inb(ahd_ddb_softc
, addr
));
1395 db_printf("%04x\n", ahd_inw(ahd_ddb_softc
, addr
));
1398 db_printf("%08x\n", ahd_inl(ahd_ddb_softc
, addr
));
1404 DB_SET(ahd_out
, ahd_ddb_out
, db_cmd_set
, CS_MORE
, NULL
)
1406 db_expr_t old_value
;
1407 db_expr_t new_value
;
1410 if (ahd_ddb_softc
== NULL
) {
1411 db_error("Must set unit with ahd_sunit first!\n");
1427 db_error("Unknown size\n");
1431 while (db_expression(&new_value
)) {
1435 old_value
= ahd_inb(ahd_ddb_softc
, addr
);
1436 ahd_outb(ahd_ddb_softc
, addr
, new_value
);
1439 old_value
= ahd_inw(ahd_ddb_softc
, addr
);
1440 ahd_outw(ahd_ddb_softc
, addr
, new_value
);
1443 old_value
= ahd_inl(ahd_ddb_softc
, addr
);
1444 ahd_outl(ahd_ddb_softc
, addr
, new_value
);
1447 db_printf("%04lx (M)%x: \t0x%lx\t=\t0x%lx",
1448 (u_long
)addr
, ahd_inb(ahd_ddb_softc
, MODE_PTR
),
1449 (u_long
)old_value
, (u_long
)new_value
);
1455 DB_COMMAND(ahd_dump
, ahd_ddb_dump
)
1457 if (ahd_ddb_softc
== NULL
) {
1458 db_error("Must set unit with ahd_sunit first!\n");
1461 ahd_dump_card_state(ahd_ddb_softc
);
1467 DECLARE_MODULE(ahd
, ahd_mod
, SI_SUB_DRIVERS
, SI_ORDER_MIDDLE
);
1468 MODULE_DEPEND(ahd
, cam
, 1, 1, 1);
1469 MODULE_VERSION(ahd
, 1);