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.21 2007/07/11 23:46:58 dillon 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 0, 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
;
167 /* We have to wait until after any system dumps... */
168 ahd
->platform_data
->eh
=
169 EVENTHANDLER_REGISTER(shutdown_post_sync
, ahd_shutdown
,
170 ahd
, SHUTDOWN_PRI_DRIVER
);
171 ahd_intr_enable(ahd
, TRUE
);
180 * Catch an interrupt from the adapter
183 ahd_platform_intr(void *arg
)
185 struct ahd_softc
*ahd
;
187 ahd
= (struct ahd_softc
*)arg
;
192 * We have an scb which has been processed by the
193 * adaptor, now we look to see how the operation
197 ahd_done(struct ahd_softc
*ahd
, struct scb
*scb
)
201 CAM_DEBUG(scb
->io_ctx
->ccb_h
.path
, CAM_DEBUG_TRACE
,
202 ("ahd_done - scb %d\n", SCB_GET_TAG(scb
)));
205 LIST_REMOVE(scb
, pending_links
);
206 if ((scb
->flags
& SCB_TIMEDOUT
) != 0)
207 LIST_REMOVE(scb
, timedout_links
);
209 callout_stop(&ccb
->ccb_h
.timeout_ch
);
211 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
214 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
215 op
= BUS_DMASYNC_POSTREAD
;
217 op
= BUS_DMASYNC_POSTWRITE
;
218 bus_dmamap_sync(ahd
->buffer_dmat
, scb
->dmamap
, op
);
219 bus_dmamap_unload(ahd
->buffer_dmat
, scb
->dmamap
);
222 #ifdef AHD_TARGET_MODE
223 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
224 struct cam_path
*ccb_path
;
227 * If we have finally disconnected, clean up our
228 * pending device state.
229 * XXX - There may be error states that cause where
230 * we will remain connected.
232 ccb_path
= ccb
->ccb_h
.path
;
233 if (ahd
->pending_device
!= NULL
234 && xpt_path_comp(ahd
->pending_device
->path
, ccb_path
) == 0) {
236 if ((ccb
->ccb_h
.flags
& CAM_SEND_STATUS
) != 0) {
237 ahd
->pending_device
= NULL
;
239 xpt_print_path(ccb
->ccb_h
.path
);
240 kprintf("Still disconnected\n");
245 if (aic_get_transaction_status(scb
) == CAM_REQ_INPROG
)
246 ccb
->ccb_h
.status
|= CAM_REQ_CMP
;
247 ccb
->ccb_h
.status
&= ~CAM_SIM_QUEUED
;
248 ahd_free_scb(ahd
, scb
);
254 if ((scb
->flags
& SCB_RECOVERY_SCB
) != 0) {
255 struct scb
*list_scb
;
257 ahd
->scb_data
.recovery_scbs
--;
259 if (aic_get_transaction_status(scb
) == CAM_BDR_SENT
260 || aic_get_transaction_status(scb
) == CAM_REQ_ABORTED
)
261 aic_set_transaction_status(scb
, CAM_CMD_TIMEOUT
);
263 if (ahd
->scb_data
.recovery_scbs
== 0) {
265 * All recovery actions have completed successfully,
266 * so reinstate the timeouts for all other pending
269 LIST_FOREACH(list_scb
,
270 &ahd
->pending_scbs
, pending_links
) {
272 aic_scb_timer_reset(list_scb
,
273 aic_get_timeout(scb
));
276 ahd_print_path(ahd
, scb
);
277 kprintf("no longer in timeout, status = %x\n",
282 /* Don't clobber any existing error state */
283 if (aic_get_transaction_status(scb
) == CAM_REQ_INPROG
) {
284 ccb
->ccb_h
.status
|= CAM_REQ_CMP
;
285 } else if ((scb
->flags
& SCB_SENSE
) != 0) {
287 * We performed autosense retrieval.
289 * Zero any sense not transferred by the
290 * device. The SCSI spec mandates that any
291 * untransfered data should be assumed to be
292 * zero. Complete the 'bounce' of sense information
293 * through buffers accessible via bus-space by
294 * copying it into the clients csio.
296 memset(&ccb
->csio
.sense_data
, 0, sizeof(ccb
->csio
.sense_data
));
297 memcpy(&ccb
->csio
.sense_data
,
298 ahd_get_sense_buf(ahd
, scb
),
299 /* XXX What size do we want to use??? */
300 sizeof(ccb
->csio
.sense_data
)
301 - ccb
->csio
.sense_resid
);
302 scb
->io_ctx
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
303 } else if ((scb
->flags
& SCB_PKT_SENSE
) != 0) {
304 struct scsi_status_iu_header
*siu
;
309 * Copy only the sense data into the provided buffer.
311 siu
= (struct scsi_status_iu_header
*)scb
->sense_data
;
312 sense_len
= MIN(scsi_4btoul(siu
->sense_length
),
313 sizeof(ccb
->csio
.sense_data
));
314 memset(&ccb
->csio
.sense_data
, 0, sizeof(ccb
->csio
.sense_data
));
315 memcpy(&ccb
->csio
.sense_data
,
316 ahd_get_sense_buf(ahd
, scb
) + SIU_SENSE_OFFSET(siu
),
318 kprintf("Copied %d bytes of sense data offset %d:", sense_len
,
319 SIU_SENSE_OFFSET(siu
));
320 for (i
= 0; i
< sense_len
; i
++)
321 kprintf(" 0x%x", ((uint8_t *)&ccb
->csio
.sense_data
)[i
]);
323 scb
->io_ctx
->ccb_h
.status
|= CAM_AUTOSNS_VALID
;
325 ccb
->ccb_h
.status
&= ~CAM_SIM_QUEUED
;
326 ahd_free_scb(ahd
, scb
);
331 ahd_action(struct cam_sim
*sim
, union ccb
*ccb
)
333 struct ahd_softc
*ahd
;
334 #ifdef AHD_TARGET_MODE
335 struct ahd_tmode_lstate
*lstate
;
340 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
, ("ahd_action\n"));
342 ahd
= (struct ahd_softc
*)cam_sim_softc(sim
);
344 target_id
= ccb
->ccb_h
.target_id
;
345 our_id
= SIM_SCSI_ID(ahd
, sim
);
347 switch (ccb
->ccb_h
.func_code
) {
348 /* Common cases first */
349 #ifdef AHD_TARGET_MODE
350 case XPT_ACCEPT_TARGET_IO
: /* Accept Host Target Mode CDB */
351 case XPT_CONT_TARGET_IO
:/* Continue Host Target I/O Connection*/
353 struct ahd_tmode_tstate
*tstate
;
356 status
= ahd_find_tmode_devs(ahd
, sim
, ccb
, &tstate
,
359 if (status
!= CAM_REQ_CMP
) {
360 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
361 /* Response from the black hole device */
363 lstate
= ahd
->black_hole
;
365 ccb
->ccb_h
.status
= status
;
370 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
);
383 * The target_id represents the target we attempt to
384 * select. In target mode, this is the initiator of
385 * the original command.
388 target_id
= ccb
->csio
.init_id
;
392 case XPT_SCSI_IO
: /* Execute the requested I/O operation */
393 case XPT_RESET_DEV
: /* Bus Device Reset the specified SCSI device */
396 struct hardware_scb
*hscb
;
397 struct ahd_initiator_tinfo
*tinfo
;
398 struct ahd_tmode_tstate
*tstate
;
401 if ((ahd
->flags
& AHD_INITIATORROLE
) == 0
402 && (ccb
->ccb_h
.func_code
== XPT_SCSI_IO
403 || ccb
->ccb_h
.func_code
== XPT_RESET_DEV
)) {
404 ccb
->ccb_h
.status
= CAM_PROVIDE_FAIL
;
413 tinfo
= ahd_fetch_transinfo(ahd
, 'A', our_id
,
415 if ((ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
) == 0
416 || (tinfo
->curr
.ppr_options
& MSG_EXT_PPR_IU_REQ
) != 0
417 || ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
418 col_idx
= AHD_NEVER_COL_IDX
;
420 col_idx
= AHD_BUILD_COL_IDX(target_id
,
421 ccb
->ccb_h
.target_lun
);
423 if ((scb
= ahd_get_scb(ahd
, col_idx
)) == NULL
) {
425 xpt_freeze_simq(sim
, /*count*/1);
426 ahd
->flags
|= AHD_RESOURCE_SHORTAGE
;
428 ccb
->ccb_h
.status
= CAM_REQUEUE_REQ
;
436 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_SUBTRACE
,
437 ("start scb(%p)\n", scb
));
440 * So we can find the SCB when an abort is requested
442 ccb
->ccb_h
.ccb_scb_ptr
= scb
;
445 * Put all the arguments for the xfer in the scb
448 hscb
->scsiid
= BUILD_SCSIID(ahd
, sim
, target_id
, our_id
);
449 hscb
->lun
= ccb
->ccb_h
.target_lun
;
450 if (ccb
->ccb_h
.func_code
== XPT_RESET_DEV
) {
452 scb
->flags
|= SCB_DEVICE_RESET
;
453 hscb
->control
|= MK_MESSAGE
;
454 hscb
->task_management
= SIU_TASKMGMT_LUN_RESET
;
455 ahd_execute_scb(scb
, NULL
, 0, 0);
457 #ifdef AHD_TARGET_MODE
458 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
459 struct target_data
*tdata
;
461 tdata
= &hscb
->shared_data
.tdata
;
462 if (ahd
->pending_device
== lstate
)
463 scb
->flags
|= SCB_TARGET_IMMEDIATE
;
464 hscb
->control
|= TARGET_SCB
;
465 tdata
->target_phases
= 0;
466 if ((ccb
->ccb_h
.flags
& CAM_SEND_STATUS
) != 0) {
467 tdata
->target_phases
|= SPHASE_PENDING
;
469 ccb
->csio
.scsi_status
;
471 if (ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
)
472 tdata
->target_phases
|= NO_DISCONNECT
;
474 tdata
->initiator_tag
=
475 ahd_htole16(ccb
->csio
.tag_id
);
478 hscb
->task_management
= 0;
479 if (ccb
->ccb_h
.flags
& CAM_TAG_ACTION_VALID
)
480 hscb
->control
|= ccb
->csio
.tag_action
;
482 ahd_setup_data(ahd
, sim
, &ccb
->csio
, scb
);
486 #ifdef AHD_TARGET_MODE
488 case XPT_IMMED_NOTIFY
:
490 struct ahd_tmode_tstate
*tstate
;
491 struct ahd_tmode_lstate
*lstate
;
494 status
= ahd_find_tmode_devs(ahd
, sim
, ccb
, &tstate
,
497 if (status
!= CAM_REQ_CMP
) {
498 ccb
->ccb_h
.status
= status
;
502 SLIST_INSERT_HEAD(&lstate
->immed_notifies
, &ccb
->ccb_h
,
504 ccb
->ccb_h
.status
= CAM_REQ_INPROG
;
505 ahd_send_lstate_events(ahd
, lstate
);
508 case XPT_EN_LUN
: /* Enable LUN as a target */
509 ahd_handle_en_lun(ahd
, sim
, ccb
);
513 case XPT_ABORT
: /* Abort the specified CCB */
515 ahd_abort_ccb(ahd
, sim
, ccb
);
518 case XPT_SET_TRAN_SETTINGS
:
521 ahd_set_tran_settings(ahd
, SIM_SCSI_ID(ahd
, sim
),
522 SIM_CHANNEL(ahd
, sim
), &ccb
->cts
);
527 case XPT_GET_TRAN_SETTINGS
:
528 /* Get default/user set transfer settings for the target */
531 ahd_get_tran_settings(ahd
, SIM_SCSI_ID(ahd
, sim
),
532 SIM_CHANNEL(ahd
, sim
), &ccb
->cts
);
537 case XPT_CALC_GEOMETRY
:
539 cam_calc_geometry(&ccb
->ccg
, ahd
->flags
& AHD_EXTENDED_TRANS_A
);
543 case XPT_RESET_BUS
: /* Reset the specified SCSI bus */
548 found
= ahd_reset_channel(ahd
, SIM_CHANNEL(ahd
, sim
),
549 /*initiate reset*/TRUE
);
552 xpt_print_path(SIM_PATH(ahd
, sim
));
553 kprintf("SCSI bus reset delivered. "
554 "%d SCBs aborted.\n", found
);
556 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
560 case XPT_TERM_IO
: /* Terminate the I/O process */
562 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
565 case XPT_PATH_INQ
: /* Path routing inquiry */
567 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
569 cpi
->version_num
= 1; /* XXX??? */
570 cpi
->hba_inquiry
= PI_SDTR_ABLE
|PI_TAG_ABLE
;
571 if ((ahd
->features
& AHD_WIDE
) != 0)
572 cpi
->hba_inquiry
|= PI_WIDE_16
;
573 if ((ahd
->features
& AHD_TARGETMODE
) != 0) {
574 cpi
->target_sprt
= PIT_PROCESSOR
578 cpi
->target_sprt
= 0;
581 cpi
->hba_eng_cnt
= 0;
582 cpi
->max_target
= (ahd
->features
& AHD_WIDE
) ? 15 : 7;
583 cpi
->max_lun
= AHD_NUM_LUNS_NONPKT
- 1;
584 cpi
->initiator_id
= ahd
->our_id
;
585 if ((ahd
->flags
& AHD_RESET_BUS_A
) == 0) {
586 cpi
->hba_misc
|= PIM_NOBUSRESET
;
588 cpi
->bus_id
= cam_sim_bus(sim
);
589 cpi
->base_transfer_speed
= 3300;
590 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
591 strncpy(cpi
->hba_vid
, "Adaptec", HBA_IDLEN
);
592 strncpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
593 cpi
->unit_number
= cam_sim_unit(sim
);
594 #ifdef AHD_NEW_TRAN_SETTINGS
595 cpi
->protocol
= PROTO_SCSI
;
596 cpi
->protocol_version
= SCSI_REV_2
;
597 cpi
->transport
= XPORT_SPI
;
598 cpi
->transport_version
= 2;
599 cpi
->xport_specific
.spi
.ppr_options
= SID_SPI_CLOCK_ST
;
600 cpi
->transport_version
= 4;
601 cpi
->xport_specific
.spi
.ppr_options
= SID_SPI_CLOCK_DT_ST
;
603 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
608 ccb
->ccb_h
.status
= CAM_PROVIDE_FAIL
;
616 ahd_set_tran_settings(struct ahd_softc
*ahd
, int our_id
, char channel
,
617 struct ccb_trans_settings
*cts
)
619 #ifdef AHD_NEW_TRAN_SETTINGS
620 struct ahd_devinfo devinfo
;
621 struct ccb_trans_settings_scsi
*scsi
;
622 struct ccb_trans_settings_spi
*spi
;
623 struct ahd_initiator_tinfo
*tinfo
;
624 struct ahd_tmode_tstate
*tstate
;
625 uint16_t *discenable
;
629 scsi
= &cts
->proto_specific
.scsi
;
630 spi
= &cts
->xport_specific
.spi
;
631 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
632 cts
->ccb_h
.target_id
,
633 cts
->ccb_h
.target_lun
,
634 SIM_CHANNEL(ahd
, sim
),
636 tinfo
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
638 devinfo
.target
, &tstate
);
640 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
) {
641 update_type
|= AHD_TRANS_GOAL
;
642 discenable
= &tstate
->discenable
;
643 tagenable
= &tstate
->tagenable
;
644 tinfo
->curr
.protocol_version
= cts
->protocol_version
;
645 tinfo
->curr
.transport_version
= cts
->transport_version
;
646 tinfo
->goal
.protocol_version
= cts
->protocol_version
;
647 tinfo
->goal
.transport_version
= cts
->transport_version
;
648 } else if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
649 update_type
|= AHD_TRANS_USER
;
650 discenable
= &ahd
->user_discenable
;
651 tagenable
= &ahd
->user_tagenable
;
652 tinfo
->user
.protocol_version
= cts
->protocol_version
;
653 tinfo
->user
.transport_version
= cts
->transport_version
;
655 cts
->ccb_h
.status
= CAM_REQ_INVALID
;
659 if ((spi
->valid
& CTS_SPI_VALID_DISC
) != 0) {
660 if ((spi
->flags
& CTS_SPI_FLAGS_DISC_ENB
) != 0)
661 *discenable
|= devinfo
.target_mask
;
663 *discenable
&= ~devinfo
.target_mask
;
666 if ((scsi
->valid
& CTS_SCSI_VALID_TQ
) != 0) {
667 if ((scsi
->flags
& CTS_SCSI_FLAGS_TAG_ENB
) != 0)
668 *tagenable
|= devinfo
.target_mask
;
670 *tagenable
&= ~devinfo
.target_mask
;
673 if ((spi
->valid
& CTS_SPI_VALID_BUS_WIDTH
) != 0) {
674 ahd_validate_width(ahd
, /*tinfo limit*/NULL
,
675 &spi
->bus_width
, ROLE_UNKNOWN
);
676 ahd_set_width(ahd
, &devinfo
, spi
->bus_width
,
677 update_type
, /*paused*/FALSE
);
680 if ((spi
->valid
& CTS_SPI_VALID_PPR_OPTIONS
) == 0) {
681 if (update_type
== AHD_TRANS_USER
)
682 spi
->ppr_options
= tinfo
->user
.ppr_options
;
684 spi
->ppr_options
= tinfo
->goal
.ppr_options
;
687 if ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) == 0) {
688 if (update_type
== AHD_TRANS_USER
)
689 spi
->sync_offset
= tinfo
->user
.offset
;
691 spi
->sync_offset
= tinfo
->goal
.offset
;
694 if ((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) == 0) {
695 if (update_type
== AHD_TRANS_USER
)
696 spi
->sync_period
= tinfo
->user
.period
;
698 spi
->sync_period
= tinfo
->goal
.period
;
701 if (((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) != 0)
702 || ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) != 0)) {
705 maxsync
= AHD_SYNCRATE_MAX
;
707 if (spi
->bus_width
!= MSG_EXT_WDTR_BUS_16_BIT
)
708 spi
->ppr_options
&= ~MSG_EXT_PPR_DT_REQ
;
710 if ((*discenable
& devinfo
.target_mask
) == 0)
711 spi
->ppr_options
&= ~MSG_EXT_PPR_IU_REQ
;
713 ahd_find_syncrate(ahd
, &spi
->sync_period
,
714 &spi
->ppr_options
, maxsync
);
715 ahd_validate_offset(ahd
, /*tinfo limit*/NULL
,
716 spi
->sync_period
, &spi
->sync_offset
,
717 spi
->bus_width
, ROLE_UNKNOWN
);
719 /* We use a period of 0 to represent async */
720 if (spi
->sync_offset
== 0) {
721 spi
->sync_period
= 0;
722 spi
->ppr_options
= 0;
725 ahd_set_syncrate(ahd
, &devinfo
, spi
->sync_period
,
726 spi
->sync_offset
, spi
->ppr_options
,
727 update_type
, /*paused*/FALSE
);
729 cts
->ccb_h
.status
= CAM_REQ_CMP
;
731 struct ahd_devinfo devinfo
;
732 struct ahd_initiator_tinfo
*tinfo
;
733 struct ahd_tmode_tstate
*tstate
;
734 uint16_t *discenable
;
738 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
739 cts
->ccb_h
.target_id
,
740 cts
->ccb_h
.target_lun
,
741 SIM_CHANNEL(ahd
, sim
),
743 tinfo
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
745 devinfo
.target
, &tstate
);
747 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) != 0) {
748 update_type
|= AHD_TRANS_GOAL
;
749 discenable
= &tstate
->discenable
;
750 tagenable
= &tstate
->tagenable
;
751 } else if ((cts
->flags
& CCB_TRANS_USER_SETTINGS
) != 0) {
752 update_type
|= AHD_TRANS_USER
;
753 discenable
= &ahd
->user_discenable
;
754 tagenable
= &ahd
->user_tagenable
;
756 cts
->ccb_h
.status
= CAM_REQ_INVALID
;
760 if ((cts
->valid
& CCB_TRANS_DISC_VALID
) != 0) {
761 if ((cts
->flags
& CCB_TRANS_DISC_ENB
) != 0)
762 *discenable
|= devinfo
.target_mask
;
764 *discenable
&= ~devinfo
.target_mask
;
767 if ((cts
->valid
& CCB_TRANS_TQ_VALID
) != 0) {
768 if ((cts
->flags
& CCB_TRANS_TAG_ENB
) != 0)
769 *tagenable
|= devinfo
.target_mask
;
771 *tagenable
&= ~devinfo
.target_mask
;
774 if ((cts
->valid
& CCB_TRANS_BUS_WIDTH_VALID
) != 0) {
775 ahd_validate_width(ahd
, /*tinfo limit*/NULL
,
776 &cts
->bus_width
, ROLE_UNKNOWN
);
777 ahd_set_width(ahd
, &devinfo
, cts
->bus_width
,
778 update_type
, /*paused*/FALSE
);
781 if ((cts
->valid
& CCB_TRANS_SYNC_OFFSET_VALID
) == 0) {
782 if (update_type
== AHD_TRANS_USER
)
783 cts
->sync_offset
= tinfo
->user
.offset
;
785 cts
->sync_offset
= tinfo
->goal
.offset
;
788 if ((cts
->valid
& CCB_TRANS_SYNC_RATE_VALID
) == 0) {
789 if (update_type
== AHD_TRANS_USER
)
790 cts
->sync_period
= tinfo
->user
.period
;
792 cts
->sync_period
= tinfo
->goal
.period
;
795 if (((cts
->valid
& CCB_TRANS_SYNC_RATE_VALID
) != 0)
796 || ((cts
->valid
& CCB_TRANS_SYNC_OFFSET_VALID
) != 0)
797 || ((cts
->valid
& CCB_TRANS_TQ_VALID
) != 0)
798 || ((cts
->valid
& CCB_TRANS_DISC_VALID
) != 0)) {
802 maxsync
= AHD_SYNCRATE_MAX
;
804 if (cts
->sync_period
<= AHD_SYNCRATE_DT
805 && cts
->bus_width
== MSG_EXT_WDTR_BUS_16_BIT
) {
806 ppr_options
= tinfo
->user
.ppr_options
807 | MSG_EXT_PPR_DT_REQ
;
810 if ((*tagenable
& devinfo
.target_mask
) == 0
811 || (*discenable
& devinfo
.target_mask
) == 0)
812 ppr_options
&= ~MSG_EXT_PPR_IU_REQ
;
814 ahd_find_syncrate(ahd
, &cts
->sync_period
,
815 &ppr_options
, maxsync
);
816 ahd_validate_offset(ahd
, /*tinfo limit*/NULL
,
817 cts
->sync_period
, &cts
->sync_offset
,
818 MSG_EXT_WDTR_BUS_8_BIT
,
821 /* We use a period of 0 to represent async */
822 if (cts
->sync_offset
== 0) {
823 cts
->sync_period
= 0;
828 && tinfo
->user
.transport_version
>= 3) {
829 tinfo
->goal
.transport_version
=
830 tinfo
->user
.transport_version
;
831 tinfo
->curr
.transport_version
=
832 tinfo
->user
.transport_version
;
835 ahd_set_syncrate(ahd
, &devinfo
, cts
->sync_period
,
836 cts
->sync_offset
, ppr_options
,
837 update_type
, /*paused*/FALSE
);
839 cts
->ccb_h
.status
= CAM_REQ_CMP
;
844 ahd_get_tran_settings(struct ahd_softc
*ahd
, int our_id
, char channel
,
845 struct ccb_trans_settings
*cts
)
847 #ifdef AHD_NEW_TRAN_SETTINGS
848 struct ahd_devinfo devinfo
;
849 struct ccb_trans_settings_scsi
*scsi
;
850 struct ccb_trans_settings_spi
*spi
;
851 struct ahd_initiator_tinfo
*targ_info
;
852 struct ahd_tmode_tstate
*tstate
;
853 struct ahd_transinfo
*tinfo
;
855 scsi
= &cts
->proto_specific
.scsi
;
856 spi
= &cts
->xport_specific
.spi
;
857 ahd_compile_devinfo(&devinfo
, our_id
,
858 cts
->ccb_h
.target_id
,
859 cts
->ccb_h
.target_lun
,
860 channel
, ROLE_UNKNOWN
);
861 targ_info
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
863 devinfo
.target
, &tstate
);
865 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
)
866 tinfo
= &targ_info
->curr
;
868 tinfo
= &targ_info
->user
;
870 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
871 spi
->flags
&= ~CTS_SPI_FLAGS_DISC_ENB
;
872 if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
873 if ((ahd
->user_discenable
& devinfo
.target_mask
) != 0)
874 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
876 if ((ahd
->user_tagenable
& devinfo
.target_mask
) != 0)
877 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
879 if ((tstate
->discenable
& devinfo
.target_mask
) != 0)
880 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
882 if ((tstate
->tagenable
& devinfo
.target_mask
) != 0)
883 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
885 cts
->protocol_version
= tinfo
->protocol_version
;
886 cts
->transport_version
= tinfo
->transport_version
;
888 spi
->sync_period
= tinfo
->period
;
889 spi
->sync_offset
= tinfo
->offset
;
890 spi
->bus_width
= tinfo
->width
;
891 spi
->ppr_options
= tinfo
->ppr_options
;
893 cts
->protocol
= PROTO_SCSI
;
894 cts
->transport
= XPORT_SPI
;
895 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
896 | CTS_SPI_VALID_SYNC_OFFSET
897 | CTS_SPI_VALID_BUS_WIDTH
898 | CTS_SPI_VALID_PPR_OPTIONS
;
900 if (cts
->ccb_h
.target_lun
!= CAM_LUN_WILDCARD
) {
901 scsi
->valid
= CTS_SCSI_VALID_TQ
;
902 spi
->valid
|= CTS_SPI_VALID_DISC
;
907 cts
->ccb_h
.status
= CAM_REQ_CMP
;
909 struct ahd_devinfo devinfo
;
910 struct ahd_initiator_tinfo
*targ_info
;
911 struct ahd_tmode_tstate
*tstate
;
912 struct ahd_transinfo
*tinfo
;
914 ahd_compile_devinfo(&devinfo
, our_id
,
915 cts
->ccb_h
.target_id
,
916 cts
->ccb_h
.target_lun
,
917 channel
, ROLE_UNKNOWN
);
918 targ_info
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
920 devinfo
.target
, &tstate
);
922 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) != 0)
923 tinfo
= &targ_info
->curr
;
925 tinfo
= &targ_info
->user
;
927 cts
->flags
&= ~(CCB_TRANS_DISC_ENB
|CCB_TRANS_TAG_ENB
);
928 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) == 0) {
929 if ((ahd
->user_discenable
& devinfo
.target_mask
) != 0)
930 cts
->flags
|= CCB_TRANS_DISC_ENB
;
932 if ((ahd
->user_tagenable
& devinfo
.target_mask
) != 0)
933 cts
->flags
|= CCB_TRANS_TAG_ENB
;
935 if ((tstate
->discenable
& devinfo
.target_mask
) != 0)
936 cts
->flags
|= CCB_TRANS_DISC_ENB
;
938 if ((tstate
->tagenable
& devinfo
.target_mask
) != 0)
939 cts
->flags
|= CCB_TRANS_TAG_ENB
;
941 cts
->sync_period
= tinfo
->period
;
942 cts
->sync_offset
= tinfo
->offset
;
943 cts
->bus_width
= tinfo
->width
;
945 cts
->valid
= CCB_TRANS_SYNC_RATE_VALID
946 | CCB_TRANS_SYNC_OFFSET_VALID
947 | CCB_TRANS_BUS_WIDTH_VALID
;
949 if (cts
->ccb_h
.target_lun
!= CAM_LUN_WILDCARD
)
950 cts
->valid
|= CCB_TRANS_DISC_VALID
|CCB_TRANS_TQ_VALID
;
952 cts
->ccb_h
.status
= CAM_REQ_CMP
;
957 ahd_async(void *callback_arg
, uint32_t code
, struct cam_path
*path
, void *arg
)
959 struct ahd_softc
*ahd
;
962 sim
= (struct cam_sim
*)callback_arg
;
963 ahd
= (struct ahd_softc
*)cam_sim_softc(sim
);
967 struct ahd_devinfo devinfo
;
969 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
970 xpt_path_target_id(path
),
971 xpt_path_lun_id(path
),
972 SIM_CHANNEL(ahd
, sim
),
976 * Revert to async/narrow transfers
977 * for the next device.
980 ahd_set_width(ahd
, &devinfo
, MSG_EXT_WDTR_BUS_8_BIT
,
981 AHD_TRANS_GOAL
|AHD_TRANS_CUR
, /*paused*/FALSE
);
982 ahd_set_syncrate(ahd
, &devinfo
, /*period*/0, /*offset*/0,
983 /*ppr_options*/0, AHD_TRANS_GOAL
|AHD_TRANS_CUR
,
994 ahd_execute_scb(void *arg
, bus_dma_segment_t
*dm_segs
, int nsegments
,
999 struct ahd_softc
*ahd
;
1000 struct ahd_initiator_tinfo
*tinfo
;
1001 struct ahd_tmode_tstate
*tstate
;
1004 scb
= (struct scb
*)arg
;
1006 ahd
= scb
->ahd_softc
;
1010 aic_set_transaction_status(scb
, CAM_REQ_TOO_BIG
);
1012 aic_set_transaction_status(scb
, CAM_REQ_CMP_ERR
);
1014 bus_dmamap_unload(ahd
->buffer_dmat
, scb
->dmamap
);
1016 ahd_free_scb(ahd
, scb
);
1022 if (nsegments
!= 0) {
1024 bus_dmasync_op_t op
;
1027 /* Copy the segments into our SG list */
1028 for (i
= nsegments
, sg
= scb
->sg_list
; i
> 0; i
--) {
1030 sg
= ahd_sg_setup(ahd
, scb
, sg
, dm_segs
->ds_addr
,
1036 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
1037 op
= BUS_DMASYNC_PREREAD
;
1039 op
= BUS_DMASYNC_PREWRITE
;
1041 bus_dmamap_sync(ahd
->buffer_dmat
, scb
->dmamap
, op
);
1043 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
1044 struct target_data
*tdata
;
1046 tdata
= &scb
->hscb
->shared_data
.tdata
;
1047 tdata
->target_phases
|= DPHASE_PENDING
;
1048 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_OUT
)
1049 tdata
->data_phase
= P_DATAOUT
;
1051 tdata
->data_phase
= P_DATAIN
;
1058 * Last time we need to check if this SCB needs to
1061 if (aic_get_transaction_status(scb
) != CAM_REQ_INPROG
) {
1063 bus_dmamap_unload(ahd
->buffer_dmat
,
1065 ahd_free_scb(ahd
, scb
);
1071 tinfo
= ahd_fetch_transinfo(ahd
, SCSIID_CHANNEL(ahd
, scb
->hscb
->scsiid
),
1072 SCSIID_OUR_ID(scb
->hscb
->scsiid
),
1073 SCSIID_TARGET(ahd
, scb
->hscb
->scsiid
),
1076 mask
= SCB_GET_TARGET_MASK(ahd
, scb
);
1078 if ((tstate
->discenable
& mask
) != 0
1079 && (ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
) == 0)
1080 scb
->hscb
->control
|= DISCENB
;
1082 if ((tinfo
->curr
.ppr_options
& MSG_EXT_PPR_IU_REQ
) != 0) {
1083 scb
->flags
|= SCB_PACKETIZED
;
1084 if (scb
->hscb
->task_management
!= 0)
1085 scb
->hscb
->control
&= ~MK_MESSAGE
;
1088 if ((ccb
->ccb_h
.flags
& CAM_NEGOTIATE
) != 0
1089 && (tinfo
->goal
.width
!= 0
1090 || tinfo
->goal
.period
!= 0
1091 || tinfo
->goal
.ppr_options
!= 0)) {
1092 scb
->flags
|= SCB_NEGOTIATE
;
1093 scb
->hscb
->control
|= MK_MESSAGE
;
1094 } else if ((tstate
->auto_negotiate
& mask
) != 0) {
1095 scb
->flags
|= SCB_AUTO_NEGOTIATE
;
1096 scb
->hscb
->control
|= MK_MESSAGE
;
1099 LIST_INSERT_HEAD(&ahd
->pending_scbs
, scb
, pending_links
);
1101 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
1103 aic_scb_timer_start(scb
);
1105 if ((scb
->flags
& SCB_TARGET_IMMEDIATE
) != 0) {
1106 /* Define a mapping from our tag to the SCB. */
1107 ahd
->scb_data
.scbindex
[SCB_GET_TAG(scb
)] = scb
;
1109 ahd_set_scbptr(ahd
, SCB_GET_TAG(scb
));
1110 ahd_outb(ahd
, RETURN_1
, CONT_MSG_LOOP_TARG
);
1113 ahd_queue_scb(ahd
, scb
);
1120 ahd_poll(struct cam_sim
*sim
)
1122 ahd_intr(cam_sim_softc(sim
));
1126 ahd_setup_data(struct ahd_softc
*ahd
, struct cam_sim
*sim
,
1127 struct ccb_scsiio
*csio
, struct scb
*scb
)
1129 struct hardware_scb
*hscb
;
1130 struct ccb_hdr
*ccb_h
;
1133 ccb_h
= &csio
->ccb_h
;
1136 csio
->sense_resid
= 0;
1137 if (ccb_h
->func_code
== XPT_SCSI_IO
) {
1138 hscb
->cdb_len
= csio
->cdb_len
;
1139 if ((ccb_h
->flags
& CAM_CDB_POINTER
) != 0) {
1141 if (hscb
->cdb_len
> MAX_CDB_LEN
1142 && (ccb_h
->flags
& CAM_CDB_PHYS
) == 0) {
1144 * Should CAM start to support CDB sizes
1145 * greater than 16 bytes, we could use
1146 * the sense buffer to store the CDB.
1148 aic_set_transaction_status(scb
,
1151 ahd_free_scb(ahd
, scb
);
1153 xpt_done((union ccb
*)csio
);
1156 if ((ccb_h
->flags
& CAM_CDB_PHYS
) != 0) {
1157 hscb
->shared_data
.idata
.cdb_from_host
.cdbptr
=
1158 aic_htole64((uintptr_t)csio
->cdb_io
.cdb_ptr
);
1159 hscb
->shared_data
.idata
.cdb_from_host
.cdblen
=
1161 hscb
->cdb_len
|= SCB_CDB_LEN_PTR
;
1163 memcpy(hscb
->shared_data
.idata
.cdb
,
1164 csio
->cdb_io
.cdb_ptr
,
1168 if (hscb
->cdb_len
> MAX_CDB_LEN
) {
1169 aic_set_transaction_status(scb
,
1172 ahd_free_scb(ahd
, scb
);
1174 xpt_done((union ccb
*)csio
);
1177 memcpy(hscb
->shared_data
.idata
.cdb
,
1178 csio
->cdb_io
.cdb_bytes
, hscb
->cdb_len
);
1182 /* Only use S/G if there is a transfer */
1183 if ((ccb_h
->flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
1184 if ((ccb_h
->flags
& CAM_SCATTER_VALID
) == 0) {
1185 /* We've been given a pointer to a single buffer */
1186 if ((ccb_h
->flags
& CAM_DATA_PHYS
) == 0) {
1190 error
= bus_dmamap_load(ahd
->buffer_dmat
,
1196 if (error
== EINPROGRESS
) {
1198 * So as to maintain ordering,
1199 * freeze the controller queue
1200 * until our mapping is
1203 xpt_freeze_simq(sim
,
1205 scb
->io_ctx
->ccb_h
.status
|=
1210 struct bus_dma_segment seg
;
1212 /* Pointer to physical buffer */
1213 if (csio
->dxfer_len
> AHD_MAXTRANSFER_SIZE
)
1214 panic("ahd_setup_data - Transfer size "
1215 "larger than can device max");
1218 (bus_addr_t
)(vm_offset_t
)csio
->data_ptr
;
1219 seg
.ds_len
= csio
->dxfer_len
;
1220 ahd_execute_scb(scb
, &seg
, 1, 0);
1223 struct bus_dma_segment
*segs
;
1225 if ((ccb_h
->flags
& CAM_DATA_PHYS
) != 0)
1226 panic("ahd_setup_data - Physical segment "
1227 "pointers unsupported");
1229 if ((ccb_h
->flags
& CAM_SG_LIST_PHYS
) == 0)
1230 panic("ahd_setup_data - Virtual segment "
1231 "addresses unsupported");
1233 /* Just use the segments provided */
1234 segs
= (struct bus_dma_segment
*)csio
->data_ptr
;
1235 ahd_execute_scb(scb
, segs
, csio
->sglist_cnt
, 0);
1238 ahd_execute_scb(scb
, NULL
, 0, 0);
1243 ahd_abort_ccb(struct ahd_softc
*ahd
, struct cam_sim
*sim
, union ccb
*ccb
)
1245 union ccb
*abort_ccb
;
1247 abort_ccb
= ccb
->cab
.abort_ccb
;
1248 switch (abort_ccb
->ccb_h
.func_code
) {
1249 #ifdef AHD_TARGET_MODE
1250 case XPT_ACCEPT_TARGET_IO
:
1251 case XPT_IMMED_NOTIFY
:
1252 case XPT_CONT_TARGET_IO
:
1254 struct ahd_tmode_tstate
*tstate
;
1255 struct ahd_tmode_lstate
*lstate
;
1256 struct ccb_hdr_slist
*list
;
1259 status
= ahd_find_tmode_devs(ahd
, sim
, abort_ccb
, &tstate
,
1262 if (status
!= CAM_REQ_CMP
) {
1263 ccb
->ccb_h
.status
= status
;
1267 if (abort_ccb
->ccb_h
.func_code
== XPT_ACCEPT_TARGET_IO
)
1268 list
= &lstate
->accept_tios
;
1269 else if (abort_ccb
->ccb_h
.func_code
== XPT_IMMED_NOTIFY
)
1270 list
= &lstate
->immed_notifies
;
1275 struct ccb_hdr
*curelm
;
1278 curelm
= SLIST_FIRST(list
);
1280 if (curelm
== &abort_ccb
->ccb_h
) {
1282 SLIST_REMOVE_HEAD(list
, sim_links
.sle
);
1284 while(curelm
!= NULL
) {
1285 struct ccb_hdr
*nextelm
;
1288 SLIST_NEXT(curelm
, sim_links
.sle
);
1290 if (nextelm
== &abort_ccb
->ccb_h
) {
1303 abort_ccb
->ccb_h
.status
= CAM_REQ_ABORTED
;
1304 xpt_done(abort_ccb
);
1305 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1307 xpt_print_path(abort_ccb
->ccb_h
.path
);
1308 kprintf("Not found\n");
1309 ccb
->ccb_h
.status
= CAM_PATH_INVALID
;
1317 /* XXX Fully implement the hard ones */
1318 ccb
->ccb_h
.status
= CAM_UA_ABORT
;
1321 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1328 ahd_send_async(struct ahd_softc
*ahd
, char channel
, u_int target
,
1329 u_int lun
, ac_code code
, void *opt_arg
)
1331 struct ccb_trans_settings cts
;
1332 struct cam_path
*path
;
1337 error
= ahd_create_path(ahd
, channel
, target
, lun
, &path
);
1339 if (error
!= CAM_REQ_CMP
)
1343 case AC_TRANSFER_NEG
:
1345 #ifdef AHD_NEW_TRAN_SETTINGS
1346 struct ccb_trans_settings_scsi
*scsi
;
1348 cts
.type
= CTS_TYPE_CURRENT_SETTINGS
;
1349 scsi
= &cts
.proto_specific
.scsi
;
1351 cts
.flags
= CCB_TRANS_CURRENT_SETTINGS
;
1353 cts
.ccb_h
.path
= path
;
1354 cts
.ccb_h
.target_id
= target
;
1355 cts
.ccb_h
.target_lun
= lun
;
1356 ahd_get_tran_settings(ahd
, ahd
->our_id
, channel
, &cts
);
1358 #ifdef AHD_NEW_TRAN_SETTINGS
1359 scsi
->valid
&= ~CTS_SCSI_VALID_TQ
;
1360 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
1362 cts
.valid
&= ~CCB_TRANS_TQ_VALID
;
1363 cts
.flags
&= ~CCB_TRANS_TAG_ENB
;
1365 if (opt_arg
== NULL
)
1367 if (*((ahd_queue_alg
*)opt_arg
) == AHD_QUEUE_TAGGED
)
1368 #ifdef AHD_NEW_TRAN_SETTINGS
1369 scsi
->flags
|= ~CTS_SCSI_FLAGS_TAG_ENB
;
1370 scsi
->valid
|= CTS_SCSI_VALID_TQ
;
1372 cts
.flags
|= CCB_TRANS_TAG_ENB
;
1373 cts
.valid
|= CCB_TRANS_TQ_VALID
;
1381 panic("ahd_send_async: Unexpected async event");
1383 xpt_async(code
, path
, arg
);
1384 xpt_free_path(path
);
1388 ahd_platform_set_tags(struct ahd_softc
*ahd
,
1389 struct ahd_devinfo
*devinfo
, int enable
)
1394 ahd_platform_alloc(struct ahd_softc
*ahd
, void *platform_arg
)
1396 ahd
->platform_data
= kmalloc(sizeof(struct ahd_platform_data
), M_DEVBUF
,
1397 M_INTWAIT
| M_ZERO
);
1402 ahd_platform_free(struct ahd_softc
*ahd
)
1404 struct ahd_platform_data
*pdata
;
1406 pdata
= ahd
->platform_data
;
1407 if (pdata
!= NULL
) {
1408 if (pdata
->regs
[0] != NULL
)
1409 bus_release_resource(ahd
->dev_softc
,
1410 pdata
->regs_res_type
[0],
1411 pdata
->regs_res_id
[0],
1414 if (pdata
->regs
[1] != NULL
)
1415 bus_release_resource(ahd
->dev_softc
,
1416 pdata
->regs_res_type
[1],
1417 pdata
->regs_res_id
[1],
1420 if (pdata
->irq
!= NULL
)
1421 bus_release_resource(ahd
->dev_softc
,
1422 pdata
->irq_res_type
,
1425 if (pdata
->sim
!= NULL
) {
1426 xpt_async(AC_LOST_DEVICE
, pdata
->path
, NULL
);
1427 xpt_free_path(pdata
->path
);
1428 xpt_bus_deregister(cam_sim_path(pdata
->sim
));
1429 cam_sim_free(pdata
->sim
);
1431 if (pdata
->eh
!= NULL
)
1432 EVENTHANDLER_DEREGISTER(shutdown_post_sync
, pdata
->eh
);
1433 kfree(ahd
->platform_data
, M_DEVBUF
);
1438 ahd_softc_comp(struct ahd_softc
*lahd
, struct ahd_softc
*rahd
)
1440 /* We don't sort softcs under FreeBSD so report equal always */
1445 ahd_detach(device_t dev
)
1447 struct ahd_softc
*ahd
;
1449 device_printf(dev
, "detaching device\n");
1450 ahd
= device_get_softc(dev
);
1451 ahd
= ahd_find_softc(ahd
);
1453 device_printf(dev
, "aic7xxx already detached\n");
1456 TAILQ_REMOVE(&ahd_tailq
, ahd
, links
);
1458 ahd_intr_enable(ahd
, FALSE
);
1459 bus_teardown_intr(dev
, ahd
->platform_data
->irq
, ahd
->platform_data
->ih
);
1467 ahd_dump_targcmd(struct target_cmd
*cmd
)
1473 byte
= &cmd
->initiator_channel
;
1474 /* Debugging info for received commands */
1475 last_byte
= &cmd
[1].initiator_channel
;
1478 while (byte
< last_byte
) {
1481 kprintf("%#x", *byte
++);
1494 ahd_modevent(module_t mod
, int type
, void *data
)
1496 /* XXX Deal with busy status on unload. */
1500 static moduledata_t ahd_mod
= {
1506 /********************************** DDB Hooks *********************************/
1508 static struct ahd_softc
*ahd_ddb_softc
;
1509 static int ahd_ddb_paused
;
1510 static int ahd_ddb_paused_on_entry
;
1511 DB_COMMAND(ahd_sunit
, ahd_ddb_sunit
)
1513 struct ahd_softc
*list_ahd
;
1515 ahd_ddb_softc
= NULL
;
1516 TAILQ_FOREACH(list_ahd
, &ahd_tailq
, links
) {
1517 if (list_ahd
->unit
== addr
)
1518 ahd_ddb_softc
= list_ahd
;
1520 if (ahd_ddb_softc
== NULL
)
1521 db_error("No matching softc found!\n");
1524 DB_COMMAND(ahd_pause
, ahd_ddb_pause
)
1526 if (ahd_ddb_softc
== NULL
) {
1527 db_error("Must set unit with ahd_sunit first!\n");
1530 if (ahd_ddb_paused
== 0) {
1532 if (ahd_is_paused(ahd_ddb_softc
)) {
1533 ahd_ddb_paused_on_entry
++;
1536 ahd_pause(ahd_ddb_softc
);
1540 DB_COMMAND(ahd_unpause
, ahd_ddb_unpause
)
1542 if (ahd_ddb_softc
== NULL
) {
1543 db_error("Must set unit with ahd_sunit first!\n");
1546 if (ahd_ddb_paused
!= 0) {
1548 if (ahd_ddb_paused_on_entry
)
1550 ahd_unpause(ahd_ddb_softc
);
1551 } else if (ahd_ddb_paused_on_entry
!= 0) {
1552 /* Two unpauses to clear a paused on entry. */
1553 ahd_ddb_paused_on_entry
= 0;
1554 ahd_unpause(ahd_ddb_softc
);
1558 DB_COMMAND(ahd_in
, ahd_ddb_in
)
1563 if (ahd_ddb_softc
== NULL
) {
1564 db_error("Must set unit with ahd_sunit first!\n");
1571 while ((c
= *modif
++) != '\0') {
1587 while (--count
>= 0) {
1588 db_printf("%04lx (M)%x: \t", (u_long
)addr
,
1589 ahd_inb(ahd_ddb_softc
, MODE_PTR
));
1592 db_printf("%02x\n", ahd_inb(ahd_ddb_softc
, addr
));
1595 db_printf("%04x\n", ahd_inw(ahd_ddb_softc
, addr
));
1598 db_printf("%08x\n", ahd_inl(ahd_ddb_softc
, addr
));
1604 DB_SET(ahd_out
, ahd_ddb_out
, db_cmd_set
, CS_MORE
, NULL
)
1606 db_expr_t old_value
;
1607 db_expr_t new_value
;
1610 if (ahd_ddb_softc
== NULL
) {
1611 db_error("Must set unit with ahd_sunit first!\n");
1627 db_error("Unknown size\n");
1631 while (db_expression(&new_value
)) {
1635 old_value
= ahd_inb(ahd_ddb_softc
, addr
);
1636 ahd_outb(ahd_ddb_softc
, addr
, new_value
);
1639 old_value
= ahd_inw(ahd_ddb_softc
, addr
);
1640 ahd_outw(ahd_ddb_softc
, addr
, new_value
);
1643 old_value
= ahd_inl(ahd_ddb_softc
, addr
);
1644 ahd_outl(ahd_ddb_softc
, addr
, new_value
);
1647 db_printf("%04lx (M)%x: \t0x%lx\t=\t0x%lx",
1648 (u_long
)addr
, ahd_inb(ahd_ddb_softc
, MODE_PTR
),
1649 (u_long
)old_value
, (u_long
)new_value
);
1655 DB_COMMAND(ahd_dump
, ahd_ddb_dump
)
1657 if (ahd_ddb_softc
== NULL
) {
1658 db_error("Must set unit with ahd_sunit first!\n");
1661 ahd_dump_card_state(ahd_ddb_softc
);
1667 DECLARE_MODULE(ahd
, ahd_mod
, SI_SUB_DRIVERS
, SI_ORDER_MIDDLE
);
1668 MODULE_DEPEND(ahd
, cam
, 1, 1, 1);
1669 MODULE_VERSION(ahd
, 1);