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.22 2008/02/09 18:13:13 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 #ifdef AHD_NEW_TRAN_SETTINGS
585 cpi
->protocol
= PROTO_SCSI
;
586 cpi
->protocol_version
= SCSI_REV_2
;
587 cpi
->transport
= XPORT_SPI
;
588 cpi
->transport_version
= 2;
589 cpi
->xport_specific
.spi
.ppr_options
= SID_SPI_CLOCK_ST
;
590 cpi
->transport_version
= 4;
591 cpi
->xport_specific
.spi
.ppr_options
= SID_SPI_CLOCK_DT_ST
;
593 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
598 ccb
->ccb_h
.status
= CAM_PROVIDE_FAIL
;
606 ahd_set_tran_settings(struct ahd_softc
*ahd
, int our_id
, char channel
,
607 struct ccb_trans_settings
*cts
)
609 #ifdef AHD_NEW_TRAN_SETTINGS
610 struct ahd_devinfo devinfo
;
611 struct ccb_trans_settings_scsi
*scsi
;
612 struct ccb_trans_settings_spi
*spi
;
613 struct ahd_initiator_tinfo
*tinfo
;
614 struct ahd_tmode_tstate
*tstate
;
615 uint16_t *discenable
;
619 scsi
= &cts
->proto_specific
.scsi
;
620 spi
= &cts
->xport_specific
.spi
;
621 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
622 cts
->ccb_h
.target_id
,
623 cts
->ccb_h
.target_lun
,
624 SIM_CHANNEL(ahd
, sim
),
626 tinfo
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
628 devinfo
.target
, &tstate
);
630 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
) {
631 update_type
|= AHD_TRANS_GOAL
;
632 discenable
= &tstate
->discenable
;
633 tagenable
= &tstate
->tagenable
;
634 tinfo
->curr
.protocol_version
= cts
->protocol_version
;
635 tinfo
->curr
.transport_version
= cts
->transport_version
;
636 tinfo
->goal
.protocol_version
= cts
->protocol_version
;
637 tinfo
->goal
.transport_version
= cts
->transport_version
;
638 } else if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
639 update_type
|= AHD_TRANS_USER
;
640 discenable
= &ahd
->user_discenable
;
641 tagenable
= &ahd
->user_tagenable
;
642 tinfo
->user
.protocol_version
= cts
->protocol_version
;
643 tinfo
->user
.transport_version
= cts
->transport_version
;
645 cts
->ccb_h
.status
= CAM_REQ_INVALID
;
649 if ((spi
->valid
& CTS_SPI_VALID_DISC
) != 0) {
650 if ((spi
->flags
& CTS_SPI_FLAGS_DISC_ENB
) != 0)
651 *discenable
|= devinfo
.target_mask
;
653 *discenable
&= ~devinfo
.target_mask
;
656 if ((scsi
->valid
& CTS_SCSI_VALID_TQ
) != 0) {
657 if ((scsi
->flags
& CTS_SCSI_FLAGS_TAG_ENB
) != 0)
658 *tagenable
|= devinfo
.target_mask
;
660 *tagenable
&= ~devinfo
.target_mask
;
663 if ((spi
->valid
& CTS_SPI_VALID_BUS_WIDTH
) != 0) {
664 ahd_validate_width(ahd
, /*tinfo limit*/NULL
,
665 &spi
->bus_width
, ROLE_UNKNOWN
);
666 ahd_set_width(ahd
, &devinfo
, spi
->bus_width
,
667 update_type
, /*paused*/FALSE
);
670 if ((spi
->valid
& CTS_SPI_VALID_PPR_OPTIONS
) == 0) {
671 if (update_type
== AHD_TRANS_USER
)
672 spi
->ppr_options
= tinfo
->user
.ppr_options
;
674 spi
->ppr_options
= tinfo
->goal
.ppr_options
;
677 if ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) == 0) {
678 if (update_type
== AHD_TRANS_USER
)
679 spi
->sync_offset
= tinfo
->user
.offset
;
681 spi
->sync_offset
= tinfo
->goal
.offset
;
684 if ((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) == 0) {
685 if (update_type
== AHD_TRANS_USER
)
686 spi
->sync_period
= tinfo
->user
.period
;
688 spi
->sync_period
= tinfo
->goal
.period
;
691 if (((spi
->valid
& CTS_SPI_VALID_SYNC_RATE
) != 0)
692 || ((spi
->valid
& CTS_SPI_VALID_SYNC_OFFSET
) != 0)) {
695 maxsync
= AHD_SYNCRATE_MAX
;
697 if (spi
->bus_width
!= MSG_EXT_WDTR_BUS_16_BIT
)
698 spi
->ppr_options
&= ~MSG_EXT_PPR_DT_REQ
;
700 if ((*discenable
& devinfo
.target_mask
) == 0)
701 spi
->ppr_options
&= ~MSG_EXT_PPR_IU_REQ
;
703 ahd_find_syncrate(ahd
, &spi
->sync_period
,
704 &spi
->ppr_options
, maxsync
);
705 ahd_validate_offset(ahd
, /*tinfo limit*/NULL
,
706 spi
->sync_period
, &spi
->sync_offset
,
707 spi
->bus_width
, ROLE_UNKNOWN
);
709 /* We use a period of 0 to represent async */
710 if (spi
->sync_offset
== 0) {
711 spi
->sync_period
= 0;
712 spi
->ppr_options
= 0;
715 ahd_set_syncrate(ahd
, &devinfo
, spi
->sync_period
,
716 spi
->sync_offset
, spi
->ppr_options
,
717 update_type
, /*paused*/FALSE
);
719 cts
->ccb_h
.status
= CAM_REQ_CMP
;
721 struct ahd_devinfo devinfo
;
722 struct ahd_initiator_tinfo
*tinfo
;
723 struct ahd_tmode_tstate
*tstate
;
724 uint16_t *discenable
;
728 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
729 cts
->ccb_h
.target_id
,
730 cts
->ccb_h
.target_lun
,
731 SIM_CHANNEL(ahd
, sim
),
733 tinfo
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
735 devinfo
.target
, &tstate
);
737 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) != 0) {
738 update_type
|= AHD_TRANS_GOAL
;
739 discenable
= &tstate
->discenable
;
740 tagenable
= &tstate
->tagenable
;
741 } else if ((cts
->flags
& CCB_TRANS_USER_SETTINGS
) != 0) {
742 update_type
|= AHD_TRANS_USER
;
743 discenable
= &ahd
->user_discenable
;
744 tagenable
= &ahd
->user_tagenable
;
746 cts
->ccb_h
.status
= CAM_REQ_INVALID
;
750 if ((cts
->valid
& CCB_TRANS_DISC_VALID
) != 0) {
751 if ((cts
->flags
& CCB_TRANS_DISC_ENB
) != 0)
752 *discenable
|= devinfo
.target_mask
;
754 *discenable
&= ~devinfo
.target_mask
;
757 if ((cts
->valid
& CCB_TRANS_TQ_VALID
) != 0) {
758 if ((cts
->flags
& CCB_TRANS_TAG_ENB
) != 0)
759 *tagenable
|= devinfo
.target_mask
;
761 *tagenable
&= ~devinfo
.target_mask
;
764 if ((cts
->valid
& CCB_TRANS_BUS_WIDTH_VALID
) != 0) {
765 ahd_validate_width(ahd
, /*tinfo limit*/NULL
,
766 &cts
->bus_width
, ROLE_UNKNOWN
);
767 ahd_set_width(ahd
, &devinfo
, cts
->bus_width
,
768 update_type
, /*paused*/FALSE
);
771 if ((cts
->valid
& CCB_TRANS_SYNC_OFFSET_VALID
) == 0) {
772 if (update_type
== AHD_TRANS_USER
)
773 cts
->sync_offset
= tinfo
->user
.offset
;
775 cts
->sync_offset
= tinfo
->goal
.offset
;
778 if ((cts
->valid
& CCB_TRANS_SYNC_RATE_VALID
) == 0) {
779 if (update_type
== AHD_TRANS_USER
)
780 cts
->sync_period
= tinfo
->user
.period
;
782 cts
->sync_period
= tinfo
->goal
.period
;
785 if (((cts
->valid
& CCB_TRANS_SYNC_RATE_VALID
) != 0)
786 || ((cts
->valid
& CCB_TRANS_SYNC_OFFSET_VALID
) != 0)
787 || ((cts
->valid
& CCB_TRANS_TQ_VALID
) != 0)
788 || ((cts
->valid
& CCB_TRANS_DISC_VALID
) != 0)) {
792 maxsync
= AHD_SYNCRATE_MAX
;
794 if (cts
->sync_period
<= AHD_SYNCRATE_DT
795 && cts
->bus_width
== MSG_EXT_WDTR_BUS_16_BIT
) {
796 ppr_options
= tinfo
->user
.ppr_options
797 | MSG_EXT_PPR_DT_REQ
;
800 if ((*tagenable
& devinfo
.target_mask
) == 0
801 || (*discenable
& devinfo
.target_mask
) == 0)
802 ppr_options
&= ~MSG_EXT_PPR_IU_REQ
;
804 ahd_find_syncrate(ahd
, &cts
->sync_period
,
805 &ppr_options
, maxsync
);
806 ahd_validate_offset(ahd
, /*tinfo limit*/NULL
,
807 cts
->sync_period
, &cts
->sync_offset
,
808 MSG_EXT_WDTR_BUS_8_BIT
,
811 /* We use a period of 0 to represent async */
812 if (cts
->sync_offset
== 0) {
813 cts
->sync_period
= 0;
818 && tinfo
->user
.transport_version
>= 3) {
819 tinfo
->goal
.transport_version
=
820 tinfo
->user
.transport_version
;
821 tinfo
->curr
.transport_version
=
822 tinfo
->user
.transport_version
;
825 ahd_set_syncrate(ahd
, &devinfo
, cts
->sync_period
,
826 cts
->sync_offset
, ppr_options
,
827 update_type
, /*paused*/FALSE
);
829 cts
->ccb_h
.status
= CAM_REQ_CMP
;
834 ahd_get_tran_settings(struct ahd_softc
*ahd
, int our_id
, char channel
,
835 struct ccb_trans_settings
*cts
)
837 #ifdef AHD_NEW_TRAN_SETTINGS
838 struct ahd_devinfo devinfo
;
839 struct ccb_trans_settings_scsi
*scsi
;
840 struct ccb_trans_settings_spi
*spi
;
841 struct ahd_initiator_tinfo
*targ_info
;
842 struct ahd_tmode_tstate
*tstate
;
843 struct ahd_transinfo
*tinfo
;
845 scsi
= &cts
->proto_specific
.scsi
;
846 spi
= &cts
->xport_specific
.spi
;
847 ahd_compile_devinfo(&devinfo
, our_id
,
848 cts
->ccb_h
.target_id
,
849 cts
->ccb_h
.target_lun
,
850 channel
, ROLE_UNKNOWN
);
851 targ_info
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
853 devinfo
.target
, &tstate
);
855 if (cts
->type
== CTS_TYPE_CURRENT_SETTINGS
)
856 tinfo
= &targ_info
->curr
;
858 tinfo
= &targ_info
->user
;
860 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
861 spi
->flags
&= ~CTS_SPI_FLAGS_DISC_ENB
;
862 if (cts
->type
== CTS_TYPE_USER_SETTINGS
) {
863 if ((ahd
->user_discenable
& devinfo
.target_mask
) != 0)
864 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
866 if ((ahd
->user_tagenable
& devinfo
.target_mask
) != 0)
867 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
869 if ((tstate
->discenable
& devinfo
.target_mask
) != 0)
870 spi
->flags
|= CTS_SPI_FLAGS_DISC_ENB
;
872 if ((tstate
->tagenable
& devinfo
.target_mask
) != 0)
873 scsi
->flags
|= CTS_SCSI_FLAGS_TAG_ENB
;
875 cts
->protocol_version
= tinfo
->protocol_version
;
876 cts
->transport_version
= tinfo
->transport_version
;
878 spi
->sync_period
= tinfo
->period
;
879 spi
->sync_offset
= tinfo
->offset
;
880 spi
->bus_width
= tinfo
->width
;
881 spi
->ppr_options
= tinfo
->ppr_options
;
883 cts
->protocol
= PROTO_SCSI
;
884 cts
->transport
= XPORT_SPI
;
885 spi
->valid
= CTS_SPI_VALID_SYNC_RATE
886 | CTS_SPI_VALID_SYNC_OFFSET
887 | CTS_SPI_VALID_BUS_WIDTH
888 | CTS_SPI_VALID_PPR_OPTIONS
;
890 if (cts
->ccb_h
.target_lun
!= CAM_LUN_WILDCARD
) {
891 scsi
->valid
= CTS_SCSI_VALID_TQ
;
892 spi
->valid
|= CTS_SPI_VALID_DISC
;
897 cts
->ccb_h
.status
= CAM_REQ_CMP
;
899 struct ahd_devinfo devinfo
;
900 struct ahd_initiator_tinfo
*targ_info
;
901 struct ahd_tmode_tstate
*tstate
;
902 struct ahd_transinfo
*tinfo
;
904 ahd_compile_devinfo(&devinfo
, our_id
,
905 cts
->ccb_h
.target_id
,
906 cts
->ccb_h
.target_lun
,
907 channel
, ROLE_UNKNOWN
);
908 targ_info
= ahd_fetch_transinfo(ahd
, devinfo
.channel
,
910 devinfo
.target
, &tstate
);
912 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) != 0)
913 tinfo
= &targ_info
->curr
;
915 tinfo
= &targ_info
->user
;
917 cts
->flags
&= ~(CCB_TRANS_DISC_ENB
|CCB_TRANS_TAG_ENB
);
918 if ((cts
->flags
& CCB_TRANS_CURRENT_SETTINGS
) == 0) {
919 if ((ahd
->user_discenable
& devinfo
.target_mask
) != 0)
920 cts
->flags
|= CCB_TRANS_DISC_ENB
;
922 if ((ahd
->user_tagenable
& devinfo
.target_mask
) != 0)
923 cts
->flags
|= CCB_TRANS_TAG_ENB
;
925 if ((tstate
->discenable
& devinfo
.target_mask
) != 0)
926 cts
->flags
|= CCB_TRANS_DISC_ENB
;
928 if ((tstate
->tagenable
& devinfo
.target_mask
) != 0)
929 cts
->flags
|= CCB_TRANS_TAG_ENB
;
931 cts
->sync_period
= tinfo
->period
;
932 cts
->sync_offset
= tinfo
->offset
;
933 cts
->bus_width
= tinfo
->width
;
935 cts
->valid
= CCB_TRANS_SYNC_RATE_VALID
936 | CCB_TRANS_SYNC_OFFSET_VALID
937 | CCB_TRANS_BUS_WIDTH_VALID
;
939 if (cts
->ccb_h
.target_lun
!= CAM_LUN_WILDCARD
)
940 cts
->valid
|= CCB_TRANS_DISC_VALID
|CCB_TRANS_TQ_VALID
;
942 cts
->ccb_h
.status
= CAM_REQ_CMP
;
947 ahd_async(void *callback_arg
, uint32_t code
, struct cam_path
*path
, void *arg
)
949 struct ahd_softc
*ahd
;
952 sim
= (struct cam_sim
*)callback_arg
;
953 ahd
= (struct ahd_softc
*)cam_sim_softc(sim
);
957 struct ahd_devinfo devinfo
;
959 ahd_compile_devinfo(&devinfo
, SIM_SCSI_ID(ahd
, sim
),
960 xpt_path_target_id(path
),
961 xpt_path_lun_id(path
),
962 SIM_CHANNEL(ahd
, sim
),
966 * Revert to async/narrow transfers
967 * for the next device.
969 ahd_set_width(ahd
, &devinfo
, MSG_EXT_WDTR_BUS_8_BIT
,
970 AHD_TRANS_GOAL
|AHD_TRANS_CUR
, /*paused*/FALSE
);
971 ahd_set_syncrate(ahd
, &devinfo
, /*period*/0, /*offset*/0,
972 /*ppr_options*/0, AHD_TRANS_GOAL
|AHD_TRANS_CUR
,
982 ahd_execute_scb(void *arg
, bus_dma_segment_t
*dm_segs
, int nsegments
,
987 struct ahd_softc
*ahd
;
988 struct ahd_initiator_tinfo
*tinfo
;
989 struct ahd_tmode_tstate
*tstate
;
992 scb
= (struct scb
*)arg
;
994 ahd
= scb
->ahd_softc
;
998 aic_set_transaction_status(scb
, CAM_REQ_TOO_BIG
);
1000 aic_set_transaction_status(scb
, CAM_REQ_CMP_ERR
);
1002 bus_dmamap_unload(ahd
->buffer_dmat
, scb
->dmamap
);
1003 ahd_free_scb(ahd
, scb
);
1008 if (nsegments
!= 0) {
1010 bus_dmasync_op_t op
;
1013 /* Copy the segments into our SG list */
1014 for (i
= nsegments
, sg
= scb
->sg_list
; i
> 0; i
--) {
1016 sg
= ahd_sg_setup(ahd
, scb
, sg
, dm_segs
->ds_addr
,
1022 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_IN
)
1023 op
= BUS_DMASYNC_PREREAD
;
1025 op
= BUS_DMASYNC_PREWRITE
;
1027 bus_dmamap_sync(ahd
->buffer_dmat
, scb
->dmamap
, op
);
1029 if (ccb
->ccb_h
.func_code
== XPT_CONT_TARGET_IO
) {
1030 struct target_data
*tdata
;
1032 tdata
= &scb
->hscb
->shared_data
.tdata
;
1033 tdata
->target_phases
|= DPHASE_PENDING
;
1034 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) == CAM_DIR_OUT
)
1035 tdata
->data_phase
= P_DATAOUT
;
1037 tdata
->data_phase
= P_DATAIN
;
1042 * Last time we need to check if this SCB needs to
1045 if (aic_get_transaction_status(scb
) != CAM_REQ_INPROG
) {
1047 bus_dmamap_unload(ahd
->buffer_dmat
,
1049 ahd_free_scb(ahd
, scb
);
1054 tinfo
= ahd_fetch_transinfo(ahd
, SCSIID_CHANNEL(ahd
, scb
->hscb
->scsiid
),
1055 SCSIID_OUR_ID(scb
->hscb
->scsiid
),
1056 SCSIID_TARGET(ahd
, scb
->hscb
->scsiid
),
1059 mask
= SCB_GET_TARGET_MASK(ahd
, scb
);
1061 if ((tstate
->discenable
& mask
) != 0
1062 && (ccb
->ccb_h
.flags
& CAM_DIS_DISCONNECT
) == 0)
1063 scb
->hscb
->control
|= DISCENB
;
1065 if ((tinfo
->curr
.ppr_options
& MSG_EXT_PPR_IU_REQ
) != 0) {
1066 scb
->flags
|= SCB_PACKETIZED
;
1067 if (scb
->hscb
->task_management
!= 0)
1068 scb
->hscb
->control
&= ~MK_MESSAGE
;
1071 if ((ccb
->ccb_h
.flags
& CAM_NEGOTIATE
) != 0
1072 && (tinfo
->goal
.width
!= 0
1073 || tinfo
->goal
.period
!= 0
1074 || tinfo
->goal
.ppr_options
!= 0)) {
1075 scb
->flags
|= SCB_NEGOTIATE
;
1076 scb
->hscb
->control
|= MK_MESSAGE
;
1077 } else if ((tstate
->auto_negotiate
& mask
) != 0) {
1078 scb
->flags
|= SCB_AUTO_NEGOTIATE
;
1079 scb
->hscb
->control
|= MK_MESSAGE
;
1082 LIST_INSERT_HEAD(&ahd
->pending_scbs
, scb
, pending_links
);
1084 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
1086 aic_scb_timer_start(scb
);
1088 if ((scb
->flags
& SCB_TARGET_IMMEDIATE
) != 0) {
1089 /* Define a mapping from our tag to the SCB. */
1090 ahd
->scb_data
.scbindex
[SCB_GET_TAG(scb
)] = scb
;
1092 ahd_set_scbptr(ahd
, SCB_GET_TAG(scb
));
1093 ahd_outb(ahd
, RETURN_1
, CONT_MSG_LOOP_TARG
);
1096 ahd_queue_scb(ahd
, scb
);
1101 ahd_poll(struct cam_sim
*sim
)
1103 ahd_intr(cam_sim_softc(sim
));
1107 ahd_setup_data(struct ahd_softc
*ahd
, struct cam_sim
*sim
,
1108 struct ccb_scsiio
*csio
, struct scb
*scb
)
1110 struct hardware_scb
*hscb
;
1111 struct ccb_hdr
*ccb_h
;
1114 ccb_h
= &csio
->ccb_h
;
1117 csio
->sense_resid
= 0;
1118 if (ccb_h
->func_code
== XPT_SCSI_IO
) {
1119 hscb
->cdb_len
= csio
->cdb_len
;
1120 if ((ccb_h
->flags
& CAM_CDB_POINTER
) != 0) {
1122 if (hscb
->cdb_len
> MAX_CDB_LEN
1123 && (ccb_h
->flags
& CAM_CDB_PHYS
) == 0) {
1126 * Should CAM start to support CDB sizes
1127 * greater than 16 bytes, we could use
1128 * the sense buffer to store the CDB.
1130 aic_set_transaction_status(scb
,
1132 ahd_free_scb(ahd
, scb
);
1133 xpt_done((union ccb
*)csio
);
1136 if ((ccb_h
->flags
& CAM_CDB_PHYS
) != 0) {
1137 hscb
->shared_data
.idata
.cdb_from_host
.cdbptr
=
1138 aic_htole64((uintptr_t)csio
->cdb_io
.cdb_ptr
);
1139 hscb
->shared_data
.idata
.cdb_from_host
.cdblen
=
1141 hscb
->cdb_len
|= SCB_CDB_LEN_PTR
;
1143 memcpy(hscb
->shared_data
.idata
.cdb
,
1144 csio
->cdb_io
.cdb_ptr
,
1148 if (hscb
->cdb_len
> MAX_CDB_LEN
) {
1150 aic_set_transaction_status(scb
,
1152 ahd_free_scb(ahd
, scb
);
1153 xpt_done((union ccb
*)csio
);
1156 memcpy(hscb
->shared_data
.idata
.cdb
,
1157 csio
->cdb_io
.cdb_bytes
, hscb
->cdb_len
);
1161 /* Only use S/G if there is a transfer */
1162 if ((ccb_h
->flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
) {
1163 if ((ccb_h
->flags
& CAM_SCATTER_VALID
) == 0) {
1164 /* We've been given a pointer to a single buffer */
1165 if ((ccb_h
->flags
& CAM_DATA_PHYS
) == 0) {
1169 error
= bus_dmamap_load(ahd
->buffer_dmat
,
1175 if (error
== EINPROGRESS
) {
1177 * So as to maintain ordering,
1178 * freeze the controller queue
1179 * until our mapping is
1182 xpt_freeze_simq(sim
,
1184 scb
->io_ctx
->ccb_h
.status
|=
1189 struct bus_dma_segment seg
;
1191 /* Pointer to physical buffer */
1192 if (csio
->dxfer_len
> AHD_MAXTRANSFER_SIZE
)
1193 panic("ahd_setup_data - Transfer size "
1194 "larger than can device max");
1197 (bus_addr_t
)(vm_offset_t
)csio
->data_ptr
;
1198 seg
.ds_len
= csio
->dxfer_len
;
1199 ahd_execute_scb(scb
, &seg
, 1, 0);
1202 struct bus_dma_segment
*segs
;
1204 if ((ccb_h
->flags
& CAM_DATA_PHYS
) != 0)
1205 panic("ahd_setup_data - Physical segment "
1206 "pointers unsupported");
1208 if ((ccb_h
->flags
& CAM_SG_LIST_PHYS
) == 0)
1209 panic("ahd_setup_data - Virtual segment "
1210 "addresses unsupported");
1212 /* Just use the segments provided */
1213 segs
= (struct bus_dma_segment
*)csio
->data_ptr
;
1214 ahd_execute_scb(scb
, segs
, csio
->sglist_cnt
, 0);
1217 ahd_execute_scb(scb
, NULL
, 0, 0);
1222 ahd_abort_ccb(struct ahd_softc
*ahd
, struct cam_sim
*sim
, union ccb
*ccb
)
1224 union ccb
*abort_ccb
;
1226 abort_ccb
= ccb
->cab
.abort_ccb
;
1227 switch (abort_ccb
->ccb_h
.func_code
) {
1228 #ifdef AHD_TARGET_MODE
1229 case XPT_ACCEPT_TARGET_IO
:
1230 case XPT_IMMED_NOTIFY
:
1231 case XPT_CONT_TARGET_IO
:
1233 struct ahd_tmode_tstate
*tstate
;
1234 struct ahd_tmode_lstate
*lstate
;
1235 struct ccb_hdr_slist
*list
;
1238 status
= ahd_find_tmode_devs(ahd
, sim
, abort_ccb
, &tstate
,
1241 if (status
!= CAM_REQ_CMP
) {
1242 ccb
->ccb_h
.status
= status
;
1246 if (abort_ccb
->ccb_h
.func_code
== XPT_ACCEPT_TARGET_IO
)
1247 list
= &lstate
->accept_tios
;
1248 else if (abort_ccb
->ccb_h
.func_code
== XPT_IMMED_NOTIFY
)
1249 list
= &lstate
->immed_notifies
;
1254 struct ccb_hdr
*curelm
;
1257 curelm
= SLIST_FIRST(list
);
1259 if (curelm
== &abort_ccb
->ccb_h
) {
1261 SLIST_REMOVE_HEAD(list
, sim_links
.sle
);
1263 while(curelm
!= NULL
) {
1264 struct ccb_hdr
*nextelm
;
1267 SLIST_NEXT(curelm
, sim_links
.sle
);
1269 if (nextelm
== &abort_ccb
->ccb_h
) {
1282 abort_ccb
->ccb_h
.status
= CAM_REQ_ABORTED
;
1283 xpt_done(abort_ccb
);
1284 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
1286 xpt_print_path(abort_ccb
->ccb_h
.path
);
1287 kprintf("Not found\n");
1288 ccb
->ccb_h
.status
= CAM_PATH_INVALID
;
1296 /* XXX Fully implement the hard ones */
1297 ccb
->ccb_h
.status
= CAM_UA_ABORT
;
1300 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
1307 ahd_send_async(struct ahd_softc
*ahd
, char channel
, u_int target
,
1308 u_int lun
, ac_code code
, void *opt_arg
)
1310 struct ccb_trans_settings cts
;
1311 struct cam_path
*path
;
1316 error
= ahd_create_path(ahd
, channel
, target
, lun
, &path
);
1318 if (error
!= CAM_REQ_CMP
)
1322 case AC_TRANSFER_NEG
:
1324 #ifdef AHD_NEW_TRAN_SETTINGS
1325 struct ccb_trans_settings_scsi
*scsi
;
1327 cts
.type
= CTS_TYPE_CURRENT_SETTINGS
;
1328 scsi
= &cts
.proto_specific
.scsi
;
1330 cts
.flags
= CCB_TRANS_CURRENT_SETTINGS
;
1332 cts
.ccb_h
.path
= path
;
1333 cts
.ccb_h
.target_id
= target
;
1334 cts
.ccb_h
.target_lun
= lun
;
1335 ahd_get_tran_settings(ahd
, ahd
->our_id
, channel
, &cts
);
1337 #ifdef AHD_NEW_TRAN_SETTINGS
1338 scsi
->valid
&= ~CTS_SCSI_VALID_TQ
;
1339 scsi
->flags
&= ~CTS_SCSI_FLAGS_TAG_ENB
;
1341 cts
.valid
&= ~CCB_TRANS_TQ_VALID
;
1342 cts
.flags
&= ~CCB_TRANS_TAG_ENB
;
1344 if (opt_arg
== NULL
)
1346 if (*((ahd_queue_alg
*)opt_arg
) == AHD_QUEUE_TAGGED
)
1347 #ifdef AHD_NEW_TRAN_SETTINGS
1348 scsi
->flags
|= ~CTS_SCSI_FLAGS_TAG_ENB
;
1349 scsi
->valid
|= CTS_SCSI_VALID_TQ
;
1351 cts
.flags
|= CCB_TRANS_TAG_ENB
;
1352 cts
.valid
|= CCB_TRANS_TQ_VALID
;
1360 panic("ahd_send_async: Unexpected async event");
1362 xpt_async(code
, path
, arg
);
1363 xpt_free_path(path
);
1367 ahd_platform_set_tags(struct ahd_softc
*ahd
,
1368 struct ahd_devinfo
*devinfo
, int enable
)
1373 ahd_platform_alloc(struct ahd_softc
*ahd
, void *platform_arg
)
1375 ahd
->platform_data
= kmalloc(sizeof(struct ahd_platform_data
), M_DEVBUF
,
1376 M_INTWAIT
| M_ZERO
);
1381 ahd_platform_free(struct ahd_softc
*ahd
)
1383 struct ahd_platform_data
*pdata
;
1385 pdata
= ahd
->platform_data
;
1386 if (pdata
!= NULL
) {
1387 if (pdata
->regs
[0] != NULL
)
1388 bus_release_resource(ahd
->dev_softc
,
1389 pdata
->regs_res_type
[0],
1390 pdata
->regs_res_id
[0],
1393 if (pdata
->regs
[1] != NULL
)
1394 bus_release_resource(ahd
->dev_softc
,
1395 pdata
->regs_res_type
[1],
1396 pdata
->regs_res_id
[1],
1399 if (pdata
->irq
!= NULL
)
1400 bus_release_resource(ahd
->dev_softc
,
1401 pdata
->irq_res_type
,
1404 if (pdata
->sim
!= NULL
) {
1405 xpt_async(AC_LOST_DEVICE
, pdata
->path
, NULL
);
1406 xpt_free_path(pdata
->path
);
1407 xpt_bus_deregister(cam_sim_path(pdata
->sim
));
1408 cam_sim_free(pdata
->sim
);
1410 if (pdata
->eh
!= NULL
)
1411 EVENTHANDLER_DEREGISTER(shutdown_post_sync
, pdata
->eh
);
1412 kfree(ahd
->platform_data
, M_DEVBUF
);
1417 ahd_softc_comp(struct ahd_softc
*lahd
, struct ahd_softc
*rahd
)
1419 /* We don't sort softcs under FreeBSD so report equal always */
1424 ahd_detach(device_t dev
)
1426 struct ahd_softc
*ahd
;
1428 device_printf(dev
, "detaching device\n");
1429 ahd
= device_get_softc(dev
);
1431 TAILQ_REMOVE(&ahd_tailq
, ahd
, links
);
1432 ahd_intr_enable(ahd
, FALSE
);
1433 bus_teardown_intr(dev
, ahd
->platform_data
->irq
, ahd
->platform_data
->ih
);
1441 ahd_dump_targcmd(struct target_cmd
*cmd
)
1447 byte
= &cmd
->initiator_channel
;
1448 /* Debugging info for received commands */
1449 last_byte
= &cmd
[1].initiator_channel
;
1452 while (byte
< last_byte
) {
1455 kprintf("%#x", *byte
++);
1468 ahd_modevent(module_t mod
, int type
, void *data
)
1470 /* XXX Deal with busy status on unload. */
1471 /* XXX Deal with unknown events */
1475 static moduledata_t ahd_mod
= {
1481 /********************************** DDB Hooks *********************************/
1483 static struct ahd_softc
*ahd_ddb_softc
;
1484 static int ahd_ddb_paused
;
1485 static int ahd_ddb_paused_on_entry
;
1486 DB_COMMAND(ahd_sunit
, ahd_ddb_sunit
)
1488 struct ahd_softc
*list_ahd
;
1490 ahd_ddb_softc
= NULL
;
1491 TAILQ_FOREACH(list_ahd
, &ahd_tailq
, links
) {
1492 if (list_ahd
->unit
== addr
)
1493 ahd_ddb_softc
= list_ahd
;
1495 if (ahd_ddb_softc
== NULL
)
1496 db_error("No matching softc found!\n");
1499 DB_COMMAND(ahd_pause
, ahd_ddb_pause
)
1501 if (ahd_ddb_softc
== NULL
) {
1502 db_error("Must set unit with ahd_sunit first!\n");
1505 if (ahd_ddb_paused
== 0) {
1507 if (ahd_is_paused(ahd_ddb_softc
)) {
1508 ahd_ddb_paused_on_entry
++;
1511 ahd_pause(ahd_ddb_softc
);
1515 DB_COMMAND(ahd_unpause
, ahd_ddb_unpause
)
1517 if (ahd_ddb_softc
== NULL
) {
1518 db_error("Must set unit with ahd_sunit first!\n");
1521 if (ahd_ddb_paused
!= 0) {
1523 if (ahd_ddb_paused_on_entry
)
1525 ahd_unpause(ahd_ddb_softc
);
1526 } else if (ahd_ddb_paused_on_entry
!= 0) {
1527 /* Two unpauses to clear a paused on entry. */
1528 ahd_ddb_paused_on_entry
= 0;
1529 ahd_unpause(ahd_ddb_softc
);
1533 DB_COMMAND(ahd_in
, ahd_ddb_in
)
1538 if (ahd_ddb_softc
== NULL
) {
1539 db_error("Must set unit with ahd_sunit first!\n");
1546 while ((c
= *modif
++) != '\0') {
1562 while (--count
>= 0) {
1563 db_printf("%04lx (M)%x: \t", (u_long
)addr
,
1564 ahd_inb(ahd_ddb_softc
, MODE_PTR
));
1567 db_printf("%02x\n", ahd_inb(ahd_ddb_softc
, addr
));
1570 db_printf("%04x\n", ahd_inw(ahd_ddb_softc
, addr
));
1573 db_printf("%08x\n", ahd_inl(ahd_ddb_softc
, addr
));
1579 DB_SET(ahd_out
, ahd_ddb_out
, db_cmd_set
, CS_MORE
, NULL
)
1581 db_expr_t old_value
;
1582 db_expr_t new_value
;
1585 if (ahd_ddb_softc
== NULL
) {
1586 db_error("Must set unit with ahd_sunit first!\n");
1602 db_error("Unknown size\n");
1606 while (db_expression(&new_value
)) {
1610 old_value
= ahd_inb(ahd_ddb_softc
, addr
);
1611 ahd_outb(ahd_ddb_softc
, addr
, new_value
);
1614 old_value
= ahd_inw(ahd_ddb_softc
, addr
);
1615 ahd_outw(ahd_ddb_softc
, addr
, new_value
);
1618 old_value
= ahd_inl(ahd_ddb_softc
, addr
);
1619 ahd_outl(ahd_ddb_softc
, addr
, new_value
);
1622 db_printf("%04lx (M)%x: \t0x%lx\t=\t0x%lx",
1623 (u_long
)addr
, ahd_inb(ahd_ddb_softc
, MODE_PTR
),
1624 (u_long
)old_value
, (u_long
)new_value
);
1630 DB_COMMAND(ahd_dump
, ahd_ddb_dump
)
1632 if (ahd_ddb_softc
== NULL
) {
1633 db_error("Must set unit with ahd_sunit first!\n");
1636 ahd_dump_card_state(ahd_ddb_softc
);
1642 DECLARE_MODULE(ahd
, ahd_mod
, SI_SUB_DRIVERS
, SI_ORDER_MIDDLE
);
1643 MODULE_DEPEND(ahd
, cam
, 1, 1, 1);
1644 MODULE_VERSION(ahd
, 1);