Deleted Added
full compact
aic7xxx.c (41646) aic7xxx.c (41816)
1/*
2 * Generic driver for the aic7xxx based adaptec SCSI controllers
3 * Product specific probe and attach routines can be found in:
4 * i386/eisa/ahc_eisa.c 27/284X and aic7770 motherboard controllers
5 * pci/ahc_pci.c 3985, 3980, 3940, 2940, aic7895, aic7890,
6 * aic7880, aic7870, aic7860, and aic7850 controllers
7 *
8 * Copyright (c) 1994, 1995, 1996, 1997, 1998 Justin T. Gibbs.

--- 22 unchanged lines hidden (view full) ---

31 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
1/*
2 * Generic driver for the aic7xxx based adaptec SCSI controllers
3 * Product specific probe and attach routines can be found in:
4 * i386/eisa/ahc_eisa.c 27/284X and aic7770 motherboard controllers
5 * pci/ahc_pci.c 3985, 3980, 3940, 2940, aic7895, aic7890,
6 * aic7880, aic7870, aic7860, and aic7850 controllers
7 *
8 * Copyright (c) 1994, 1995, 1996, 1997, 1998 Justin T. Gibbs.

--- 22 unchanged lines hidden (view full) ---

31 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * $Id: aic7xxx.c,v 1.11 1998/12/04 22:54:44 archie Exp $
39 * $Id: aic7xxx.c,v 1.12 1998/12/10 04:14:49 gibbs Exp $
40 */
41/*
42 * A few notes on features of the driver.
43 *
44 * SCB paging takes advantage of the fact that devices stay disconnected
45 * from the bus a relatively long time and that while they're disconnected,
46 * having the SCBs for these transactions down on the host adapter is of
47 * little use. Instead of leaving this idle SCB down on the card we copy

--- 202 unchanged lines hidden (view full) ---

250static int ahc_match_scb(struct scb *scb, int target, char channel,
251 int lun, u_int tag);
252#ifdef AHC_DEBUG
253static void ahc_print_scb(struct scb *scb);
254#endif
255static int ahc_search_qinfifo(struct ahc_softc *ahc, int target,
256 char channel, int lun, u_int tag,
257 u_int32_t status, ahc_search_action action);
40 */
41/*
42 * A few notes on features of the driver.
43 *
44 * SCB paging takes advantage of the fact that devices stay disconnected
45 * from the bus a relatively long time and that while they're disconnected,
46 * having the SCBs for these transactions down on the host adapter is of
47 * little use. Instead of leaving this idle SCB down on the card we copy

--- 202 unchanged lines hidden (view full) ---

250static int ahc_match_scb(struct scb *scb, int target, char channel,
251 int lun, u_int tag);
252#ifdef AHC_DEBUG
253static void ahc_print_scb(struct scb *scb);
254#endif
255static int ahc_search_qinfifo(struct ahc_softc *ahc, int target,
256 char channel, int lun, u_int tag,
257 u_int32_t status, ahc_search_action action);
258static void ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim,
259 union ccb *ccb);
258static int ahc_reset_channel(struct ahc_softc *ahc, char channel,
259 int initiate_reset);
260static int ahc_abort_scbs(struct ahc_softc *ahc, int target,
261 char channel, int lun, u_int tag,
262 u_int32_t status);
263static int ahc_search_disc_list(struct ahc_softc *ahc, int target,
264 char channel, int lun, u_int tag);
265static u_int ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,

--- 2536 unchanged lines hidden (view full) ---

2802 */
2803int
2804ahc_init(struct ahc_softc *ahc)
2805{
2806 int max_targ = 15;
2807 int i;
2808 int term;
2809 u_int scsi_conf;
260static int ahc_reset_channel(struct ahc_softc *ahc, char channel,
261 int initiate_reset);
262static int ahc_abort_scbs(struct ahc_softc *ahc, int target,
263 char channel, int lun, u_int tag,
264 u_int32_t status);
265static int ahc_search_disc_list(struct ahc_softc *ahc, int target,
266 char channel, int lun, u_int tag);
267static u_int ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,

--- 2536 unchanged lines hidden (view full) ---

2804 */
2805int
2806ahc_init(struct ahc_softc *ahc)
2807{
2808 int max_targ = 15;
2809 int i;
2810 int term;
2811 u_int scsi_conf;
2812 u_int scsiseq_template;
2810
2811#ifdef AHC_PRINT_SRAM
2812 printf("Scratch Ram:");
2813 for (i = 0x20; i < 0x5f; i++) {
2814 if (((i % 8) == 0) && (i != 0)) {
2815 printf ("\n ");
2816 }
2817 printf (" 0x%x", ahc_inb(ahc, i));

--- 116 unchanged lines hidden (view full) ---

2934 else
2935 ahc_outb(ahc, SCSIID, ahc->our_id_b);
2936 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
2937 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
2938 |term|ENSTIMER|ACTNEGEN);
2939 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
2940 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
2941
2813
2814#ifdef AHC_PRINT_SRAM
2815 printf("Scratch Ram:");
2816 for (i = 0x20; i < 0x5f; i++) {
2817 if (((i % 8) == 0) && (i != 0)) {
2818 printf ("\n ");
2819 }
2820 printf (" 0x%x", ahc_inb(ahc, i));

--- 116 unchanged lines hidden (view full) ---

2937 else
2938 ahc_outb(ahc, SCSIID, ahc->our_id_b);
2939 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
2940 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
2941 |term|ENSTIMER|ACTNEGEN);
2942 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
2943 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
2944
2942 if (scsi_conf & RESET_SCSI) {
2943 /* Reset the bus */
2944 if (bootverbose)
2945 printf("%s: Resetting Channel B\n",
2946 ahc_name(ahc));
2947 ahc_reset_current_bus(ahc);
2948 }
2945 if ((scsi_conf & RESET_SCSI) != 0
2946 && (ahc->flags & AHC_INITIATORMODE) != 0)
2947 ahc->flags |= AHC_RESET_BUS_B;
2949
2950 /* Select Channel A */
2951 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
2952 }
2953 term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
2954 if ((ahc->features & AHC_ULTRA2) != 0)
2955 ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
2956 else

--- 11 unchanged lines hidden (view full) ---

2968 while (--i && ((ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0))
2969 DELAY(100);
2970
2971 if (i == 0)
2972 panic("%s: Transceiver state never settled\n",
2973 ahc_name(ahc));
2974 }
2975
2948
2949 /* Select Channel A */
2950 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
2951 }
2952 term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
2953 if ((ahc->features & AHC_ULTRA2) != 0)
2954 ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
2955 else

--- 11 unchanged lines hidden (view full) ---

2967 while (--i && ((ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0))
2968 DELAY(100);
2969
2970 if (i == 0)
2971 panic("%s: Transceiver state never settled\n",
2972 ahc_name(ahc));
2973 }
2974
2976 if (scsi_conf & RESET_SCSI) {
2977 /* Reset the bus */
2978 if (bootverbose)
2979 printf("%s: Resetting Channel %c\n", ahc_name(ahc),
2980 ahc->channel);
2975 if ((scsi_conf & RESET_SCSI) != 0
2976 && (ahc->flags & AHC_INITIATORMODE) != 0)
2977 ahc->flags |= AHC_RESET_BUS_A;
2981
2978
2982 ahc_reset_current_bus(ahc);
2983 }
2984
2985 /*
2986 * Look at the information that board initialization or
2987 * the board bios has left us. In the lower four bits of each
2988 * target's scratch space any value other than 0 indicates
2989 * that we should initiate synchronous transfers. If it's zero,
2990 * the user or the BIOS has decided to disable synchronous
2991 * negotiation to that target so we don't activate the needsdtr
2992 * flag.

--- 218 unchanged lines hidden (view full) ---

3211
3212 /* Our disconnection list is empty too */
3213 ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
3214
3215 /* Message out buffer starts empty */
3216 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
3217
3218 /*
2979 /*
2980 * Look at the information that board initialization or
2981 * the board bios has left us. In the lower four bits of each
2982 * target's scratch space any value other than 0 indicates
2983 * that we should initiate synchronous transfers. If it's zero,
2984 * the user or the BIOS has decided to disable synchronous
2985 * negotiation to that target so we don't activate the needsdtr
2986 * flag.

--- 218 unchanged lines hidden (view full) ---

3205
3206 /* Our disconnection list is empty too */
3207 ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
3208
3209 /* Message out buffer starts empty */
3210 ahc_outb(ahc, MSG_OUT, MSG_NOOP);
3211
3212 /*
3213 * Setup the allowed SCSI Sequences based on operational mode.
3214 * If we are a target, we'll enalbe select in operations once
3215 * we've had a lun enabled.
3216 */
3217 scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
3218 if ((ahc->flags & AHC_INITIATORMODE) != 0)
3219 scsiseq_template |= ENRSELI;
3220 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
3221
3222 /*
3219 * Load the Sequencer program and Enable the adapter
3220 * in "fast" mode.
3221 */
3222 if (bootverbose)
3223 printf("%s: Downloading Sequencer Program...",
3224 ahc_name(ahc));
3225
3226 ahc_loadseq(ahc);

--- 228 unchanged lines hidden (view full) ---

3455 xpt_done(ccb);
3456 break;
3457 }
3458
3459 cel = &ccb->cel;
3460 target = ccb->ccb_h.target_id;
3461 lun = ccb->ccb_h.target_lun;
3462 if (cel->enable != 0) {
3223 * Load the Sequencer program and Enable the adapter
3224 * in "fast" mode.
3225 */
3226 if (bootverbose)
3227 printf("%s: Downloading Sequencer Program...",
3228 ahc_name(ahc));
3229
3230 ahc_loadseq(ahc);

--- 228 unchanged lines hidden (view full) ---

3459 xpt_done(ccb);
3460 break;
3461 }
3462
3463 cel = &ccb->cel;
3464 target = ccb->ccb_h.target_id;
3465 lun = ccb->ccb_h.target_lun;
3466 if (cel->enable != 0) {
3467 u_int scsiseq;
3468
3463 /* Are we already enabled?? */
3464 if (lstate != NULL) {
3465 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
3466 xpt_done(ccb);
3467 break;
3468 }
3469
3470 if (cel->grp6_len != 0

--- 27 unchanged lines hidden (view full) ---

3498 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
3499 xpt_done(ccb);
3500 break;
3501 }
3502 bzero(lstate, sizeof(*lstate));
3503 SLIST_INIT(&lstate->accept_tios);
3504 SLIST_INIT(&lstate->immed_notifies);
3505 tstate->enabled_luns[lun] = lstate;
3469 /* Are we already enabled?? */
3470 if (lstate != NULL) {
3471 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
3472 xpt_done(ccb);
3473 break;
3474 }
3475
3476 if (cel->grp6_len != 0

--- 27 unchanged lines hidden (view full) ---

3504 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
3505 xpt_done(ccb);
3506 break;
3507 }
3508 bzero(lstate, sizeof(*lstate));
3509 SLIST_INIT(&lstate->accept_tios);
3510 SLIST_INIT(&lstate->immed_notifies);
3511 tstate->enabled_luns[lun] = lstate;
3512 pause_sequencer(ahc);
3506 if ((ahc->features & AHC_MULTI_TID) != 0) {
3507 u_int16_t targid_mask;
3508
3513 if ((ahc->features & AHC_MULTI_TID) != 0) {
3514 u_int16_t targid_mask;
3515
3509 pause_sequencer(ahc);
3510 targid_mask = ahc_inb(ahc, TARGID)
3511 | (ahc_inb(ahc, TARGID + 1) << 8);
3512
3513 targid_mask |= (0x01 << target);
3514 ahc_outb(ahc, TARGID, targid_mask);
3515 ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
3516 targid_mask = ahc_inb(ahc, TARGID)
3517 | (ahc_inb(ahc, TARGID + 1) << 8);
3518
3519 targid_mask |= (0x01 << target);
3520 ahc_outb(ahc, TARGID, targid_mask);
3521 ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
3516 unpause_sequencer(ahc, /*always?*/FALSE);
3517 }
3522 }
3523 /* Allow select-in operations */
3524 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
3525 scsiseq |= ENSELI;
3526 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
3527 scsiseq = ahc_inb(ahc, SCSISEQ);
3528 scsiseq |= ENSELI;
3529 ahc_outb(ahc, SCSISEQ, scsiseq);
3530 unpause_sequencer(ahc, /*always?*/FALSE);
3518 ccb->ccb_h.status = CAM_REQ_CMP;
3519 xpt_print_path(ccb->ccb_h.path);
3520 printf("Lun now enabled for target mode\n");
3521 xpt_done(ccb);
3522 break;
3523 } else {
3531 ccb->ccb_h.status = CAM_REQ_CMP;
3532 xpt_print_path(ccb->ccb_h.path);
3533 printf("Lun now enabled for target mode\n");
3534 xpt_done(ccb);
3535 break;
3536 } else {
3537 struct ccb_hdr *elm;
3538
3524 /* XXX Fully Implement Disable */
3525 if (lstate == NULL) {
3526 ccb->ccb_h.status = CAM_LUN_INVALID;
3527 xpt_done(ccb);
3528 break;
3529 }
3539 /* XXX Fully Implement Disable */
3540 if (lstate == NULL) {
3541 ccb->ccb_h.status = CAM_LUN_INVALID;
3542 xpt_done(ccb);
3543 break;
3544 }
3545
3530 ccb->ccb_h.status = CAM_REQ_CMP;
3546 ccb->ccb_h.status = CAM_REQ_CMP;
3547 LIST_FOREACH(elm, &ahc->pending_ccbs, sim_links.le) {
3548 if (elm->func_code == XPT_CONT_TARGET_IO
3549 && !xpt_path_comp(elm->path, ccb->ccb_h.path)){
3550 ccb->ccb_h.status = CAM_REQ_INVALID;
3551 break;
3552 }
3553 }
3554
3555 if (SLIST_FIRST(&lstate->accept_tios) != NULL)
3556 ccb->ccb_h.status = CAM_REQ_INVALID;
3557
3558 if (SLIST_FIRST(&lstate->immed_notifies) != NULL)
3559 ccb->ccb_h.status = CAM_REQ_INVALID;
3560
3561 if (ccb->ccb_h.status == CAM_REQ_CMP) {
3562 int i, empty;
3563
3564 free(lstate, M_DEVBUF);
3565 tstate->enabled_luns[lun] = NULL;
3566
3567 /* Can we clean up the target too? */
3568 for (empty = 1, i = 0; i < 8; i++)
3569 if (tstate->enabled_luns[i] != NULL) {
3570 empty = 0;
3571 break;
3572 }
3573 if (empty) {
3574 printf("Target Empty\n");
3575 free(tstate, M_DEVBUF);
3576 ahc->enabled_targets[target] = NULL;
3577 pause_sequencer(ahc);
3578 if (ahc->features & AHC_MULTI_TID) {
3579 u_int16_t targid_mask;
3580
3581 targid_mask =
3582 ahc_inb(ahc, TARGID)
3583 | (ahc_inb(ahc, TARGID + 1)
3584 << 8);
3585
3586 targid_mask &= (0x01 << target);
3587 ahc_outb(ahc, TARGID,
3588 targid_mask);
3589 ahc_outb(ahc, TARGID+1,
3590 (targid_mask >> 8));
3591 }
3592
3593 for (empty = 1, i = 0; i < 16; i++)
3594 if (ahc->enabled_targets[i]
3595 != NULL) {
3596 empty = 0;
3597 break;
3598 }
3599 if (empty) {
3600 /* Disallow select-in */
3601 u_int scsiseq;
3602
3603 printf("No targets\n");
3604 scsiseq =
3605 ahc_inb(ahc,
3606 SCSISEQ_TEMPLATE);
3607 scsiseq &= ~ENSELI;
3608 ahc_outb(ahc, SCSISEQ_TEMPLATE,
3609 scsiseq);
3610 scsiseq = ahc_inb(ahc, SCSISEQ);
3611 scsiseq &= ~ENSELI;
3612 ahc_outb(ahc, SCSISEQ, scsiseq);
3613 }
3614 unpause_sequencer(ahc,
3615 /*always?*/FALSE);
3616 }
3617 }
3531 xpt_done(ccb);
3532 break;
3533 }
3534 break;
3535 }
3536 case XPT_ABORT: /* Abort the specified CCB */
3618 xpt_done(ccb);
3619 break;
3620 }
3621 break;
3622 }
3623 case XPT_ABORT: /* Abort the specified CCB */
3537 /* XXX Implement */
3538 ccb->ccb_h.status = CAM_REQ_INVALID;
3539 xpt_done(ccb);
3624 {
3625 ahc_abort_ccb(ahc, sim, ccb);
3540 break;
3626 break;
3627 }
3541 case XPT_SET_TRAN_SETTINGS:
3542 {
3543 struct ahc_devinfo devinfo;
3544 struct ccb_trans_settings *cts;
3545 struct ahc_target_tinfo *tinfo;
3546 u_int update_type;
3547 int s;
3548

--- 191 unchanged lines hidden (view full) ---

3740 if ((ahc->flags & AHC_TARGETMODE) != 0) {
3741 cpi->target_sprt = PIT_PROCESSOR
3742 | PIT_DISCONNECT
3743 | PIT_TERM_IO;
3744 } else {
3745 cpi->target_sprt = 0;
3746 }
3747 cpi->hba_misc = (ahc->flags & AHC_INITIATORMODE)
3628 case XPT_SET_TRAN_SETTINGS:
3629 {
3630 struct ahc_devinfo devinfo;
3631 struct ccb_trans_settings *cts;
3632 struct ahc_target_tinfo *tinfo;
3633 u_int update_type;
3634 int s;
3635

--- 191 unchanged lines hidden (view full) ---

3827 if ((ahc->flags & AHC_TARGETMODE) != 0) {
3828 cpi->target_sprt = PIT_PROCESSOR
3829 | PIT_DISCONNECT
3830 | PIT_TERM_IO;
3831 } else {
3832 cpi->target_sprt = 0;
3833 }
3834 cpi->hba_misc = (ahc->flags & AHC_INITIATORMODE)
3748 ? 0 : PIM_NOINITIATOR|PIM_NOBUSRESET;
3835 ? 0 : PIM_NOINITIATOR;
3749 cpi->hba_eng_cnt = 0;
3750 cpi->max_target = (ahc->features & AHC_WIDE) ? 15 : 7;
3751 cpi->max_lun = 7;
3836 cpi->hba_eng_cnt = 0;
3837 cpi->max_target = (ahc->features & AHC_WIDE) ? 15 : 7;
3838 cpi->max_lun = 7;
3752 if (SIM_IS_SCSIBUS_B(ahc, sim))
3839 if (SIM_IS_SCSIBUS_B(ahc, sim)) {
3753 cpi->initiator_id = ahc->our_id_b;
3840 cpi->initiator_id = ahc->our_id_b;
3754 else
3841 if ((ahc->flags & AHC_RESET_BUS_B) == 0)
3842 cpi->hba_misc |= PIM_NOBUSRESET;
3843 } else {
3755 cpi->initiator_id = ahc->our_id;
3844 cpi->initiator_id = ahc->our_id;
3845 if ((ahc->flags & AHC_RESET_BUS_A) == 0)
3846 cpi->hba_misc |= PIM_NOBUSRESET;
3847 }
3756 cpi->bus_id = cam_sim_bus(sim);
3757 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
3758 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
3759 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
3760 cpi->unit_number = cam_sim_unit(sim);
3761 cpi->ccb_h.status = CAM_REQ_CMP;
3762 xpt_done(ccb);
3763 break;

--- 679 unchanged lines hidden (view full) ---

4443 * idle.
4444 */
4445 printf("invalid phase, LASTPHASE == 0x%x",
4446 bus_state);
4447 bus_state = P_BUSFREE;
4448 break;
4449 }
4450
3848 cpi->bus_id = cam_sim_bus(sim);
3849 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
3850 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
3851 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
3852 cpi->unit_number = cam_sim_unit(sim);
3853 cpi->ccb_h.status = CAM_REQ_CMP;
3854 xpt_done(ccb);
3855 break;

--- 679 unchanged lines hidden (view full) ---

4535 * idle.
4536 */
4537 printf("invalid phase, LASTPHASE == 0x%x",
4538 bus_state);
4539 bus_state = P_BUSFREE;
4540 break;
4541 }
4542
4451 printf(", SCSISIGI == 0x%x\n", ahc_inb(ahc, SCSISIGI));
4543 printf(", SEQADDR == 0x%x\n",
4544 ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
4452
4545
4453 printf("SEQADDR == 0x%x\n", ahc_inb(ahc, SEQADDR0)
4454 | (ahc_inb(ahc, SEQADDR1) << 8));
4455
4546#if 0
4547 printf(", SCSISIGI == 0x%x\n", ahc_inb(ahc, SCSISIGI));
4456 printf("SIMODE1 = 0x%x\n", ahc_inb(ahc, SIMODE1));
4457 printf("INTSTAT = 0x%x\n", ahc_inb(ahc, INTSTAT));
4458 printf("SSTAT1 == 0x%x\n", ahc_inb(ahc, SSTAT1));
4548 printf("SIMODE1 = 0x%x\n", ahc_inb(ahc, SIMODE1));
4549 printf("INTSTAT = 0x%x\n", ahc_inb(ahc, INTSTAT));
4550 printf("SSTAT1 == 0x%x\n", ahc_inb(ahc, SSTAT1));
4459#if 0
4460 printf("SCSIRATE == 0x%x\n", ahc_inb(ahc, SCSIRATE));
4461 printf("CCSCBCTL == 0x%x\n", ahc_inb(ahc, CCSCBCTL));
4462 printf("CCSCBCNT == 0x%x\n", ahc_inb(ahc, CCSCBCNT));
4463 printf("DFCNTRL == 0x%x\n", ahc_inb(ahc, DFCNTRL));
4464 printf("DFSTATUS == 0x%x\n", ahc_inb(ahc, DFSTATUS));
4465 printf("CCHCNT == 0x%x\n", ahc_inb(ahc, CCHCNT));
4466#endif
4551 printf("SCSIRATE == 0x%x\n", ahc_inb(ahc, SCSIRATE));
4552 printf("CCSCBCTL == 0x%x\n", ahc_inb(ahc, CCSCBCTL));
4553 printf("CCSCBCNT == 0x%x\n", ahc_inb(ahc, CCSCBCNT));
4554 printf("DFCNTRL == 0x%x\n", ahc_inb(ahc, DFCNTRL));
4555 printf("DFSTATUS == 0x%x\n", ahc_inb(ahc, DFSTATUS));
4556 printf("CCHCNT == 0x%x\n", ahc_inb(ahc, CCHCNT));
4557#endif
4467 /* Decide our course of action */
4468 if (scb->flags & SCB_DEVICE_RESET) {
4469 /*
4470 * Been down this road before.
4471 * Do a full bus reset.
4472 */
4473bus_reset:
4474 ahc_set_ccb_status(scb->ccb, CAM_CMD_TIMEOUT);
4475 found = ahc_reset_channel(ahc, channel, /*Initiate Reset*/TRUE);
4476 printf("%s: Issued Channel %c Bus Reset. "
4477 "%d SCBs aborted\n", ahc_name(ahc), channel, found);
4478 } else {
4479 /*
4558 if (scb->flags & SCB_DEVICE_RESET) {
4559 /*
4560 * Been down this road before.
4561 * Do a full bus reset.
4562 */
4563bus_reset:
4564 ahc_set_ccb_status(scb->ccb, CAM_CMD_TIMEOUT);
4565 found = ahc_reset_channel(ahc, channel, /*Initiate Reset*/TRUE);
4566 printf("%s: Issued Channel %c Bus Reset. "
4567 "%d SCBs aborted\n", ahc_name(ahc), channel, found);
4568 } else {
4569 /*
4480 * Send a Bus Device Reset message:
4481 * The target that is holding up the bus may not
4570 * If we are a target, transition to bus free and report
4571 * the timeout.
4572 *
4573 * The target/initiator that is holding up the bus may not
4482 * be the same as the one that triggered this timeout
4483 * (different commands have different timeout lengths).
4574 * be the same as the one that triggered this timeout
4575 * (different commands have different timeout lengths).
4484 * Our strategy here is to queue a BDR message
4485 * to the timed out target if the bus is idle.
4486 * Otherwise, if we have an active target we stuff the
4487 * message buffer with a BDR message and assert ATN
4488 * in the hopes that the target will let go of the bus
4489 * and go to the mesgout phase. If this fails, we'll
4490 * get another timeout 2 seconds later which will attempt
4491 * a bus reset.
4576 * If the bus is idle and we are actiing as the initiator
4577 * for this request, queue a BDR message to the timed out
4578 * target. Otherwise, if the timed out transaction is
4579 * active:
4580 * Initiator transaction:
4581 * Stuff the message buffer with a BDR message and assert
4582 * ATN in the hopes that the target will let go of the bus
4583 * and go to the mesgout phase. If this fails, we'll
4584 * get another timeout 2 seconds later which will attempt
4585 * a bus reset.
4586 *
4587 * Target transaction:
4588 * Transition to BUS FREE and report the error.
4589 * It's good to be the target!
4492 */
4493 u_int active_scb_index;
4494
4495 active_scb_index = ahc_inb(ahc, SCB_TAG);
4496
4497 if (bus_state != P_BUSFREE
4498 && (active_scb_index < ahc->scb_data->numscbs)) {
4499 struct scb *active_scb;

--- 14 unchanged lines hidden (view full) ---

4514 newtimeout = MAX(active_scb->ccb->ccb_h.timeout,
4515 scb->ccb->ccb_h.timeout);
4516 ccbh = &scb->ccb->ccb_h;
4517 scb->ccb->ccb_h.timeout_ch =
4518 timeout(ahc_timeout, scb,
4519 (newtimeout * hz) / 1000);
4520 splx(s);
4521 return;
4590 */
4591 u_int active_scb_index;
4592
4593 active_scb_index = ahc_inb(ahc, SCB_TAG);
4594
4595 if (bus_state != P_BUSFREE
4596 && (active_scb_index < ahc->scb_data->numscbs)) {
4597 struct scb *active_scb;

--- 14 unchanged lines hidden (view full) ---

4612 newtimeout = MAX(active_scb->ccb->ccb_h.timeout,
4613 scb->ccb->ccb_h.timeout);
4614 ccbh = &scb->ccb->ccb_h;
4615 scb->ccb->ccb_h.timeout_ch =
4616 timeout(ahc_timeout, scb,
4617 (newtimeout * hz) / 1000);
4618 splx(s);
4619 return;
4620 }
4621
4622 /* It's us */
4623 if ((scb->hscb->control & TARGET_SCB) != 0) {
4624
4625 /*
4626 * Send back any queued up transactions
4627 * and properly record the error condition.
4628 */
4629 ahc_freeze_devq(ahc, scb->ccb->ccb_h.path);
4630 ahc_set_ccb_status(scb->ccb, CAM_CMD_TIMEOUT);
4631 ahc_freeze_ccb(scb->ccb);
4632 ahc_done(ahc, scb);
4633
4634 /* Will clear us from the bus */
4635 restart_sequencer(ahc);
4636 return;
4522 }
4637 }
4638
4523 ahc_set_recoveryscb(ahc, active_scb);
4524 ahc_outb(ahc, MSG_OUT, MSG_BUS_DEV_RESET);
4525 ahc_outb(ahc, SCSISIGO, bus_state|ATNO);
4526 xpt_print_path(active_scb->ccb->ccb_h.path);
4527 printf("BDR message in message buffer\n");
4528 active_scb->flags |= SCB_DEVICE_RESET;
4529 active_scb->ccb->ccb_h.timeout_ch =
4530 timeout(ahc_timeout, (caddr_t)active_scb, 2 * hz);
4531 unpause_sequencer(ahc, /*unpause_always*/TRUE);
4532 } else {
4533 int disconnected;
4534
4639 ahc_set_recoveryscb(ahc, active_scb);
4640 ahc_outb(ahc, MSG_OUT, MSG_BUS_DEV_RESET);
4641 ahc_outb(ahc, SCSISIGO, bus_state|ATNO);
4642 xpt_print_path(active_scb->ccb->ccb_h.path);
4643 printf("BDR message in message buffer\n");
4644 active_scb->flags |= SCB_DEVICE_RESET;
4645 active_scb->ccb->ccb_h.timeout_ch =
4646 timeout(ahc_timeout, (caddr_t)active_scb, 2 * hz);
4647 unpause_sequencer(ahc, /*unpause_always*/TRUE);
4648 } else {
4649 int disconnected;
4650
4651 if (bus_state != P_BUSFREE
4652 && (ahc_inb(ahc, SSTAT0) & TARGET) != 0) {
4653 /* Hung target selection. Goto busfree */
4654 printf("%s: Hung target selection\n",
4655 ahc_name(ahc));
4656 restart_sequencer(ahc);
4657 return;
4658 }
4659
4535 if (ahc_search_qinfifo(ahc, target, channel, lun,
4536 scb->hscb->tag, /*status*/0,
4537 SEARCH_COUNT) > 0) {
4538 disconnected = FALSE;
4539 } else {
4540 disconnected = TRUE;
4541 }
4542

--- 110 unchanged lines hidden (view full) ---

4653 } else {
4654 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
4655 }
4656
4657 return (found);
4658}
4659
4660
4660 if (ahc_search_qinfifo(ahc, target, channel, lun,
4661 scb->hscb->tag, /*status*/0,
4662 SEARCH_COUNT) > 0) {
4663 disconnected = FALSE;
4664 } else {
4665 disconnected = TRUE;
4666 }
4667

--- 110 unchanged lines hidden (view full) ---

4778 } else {
4779 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
4780 }
4781
4782 return (found);
4783}
4784
4785
4786static void
4787ahc_abort_ccb(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
4788{
4789 union ccb *abort_ccb;
4790
4791 abort_ccb = ccb->cab.abort_ccb;
4792 switch (abort_ccb->ccb_h.func_code) {
4793 case XPT_ACCEPT_TARGET_IO:
4794 case XPT_IMMED_NOTIFY:
4795 case XPT_CONT_TARGET_IO:
4796 {
4797 struct tmode_tstate *tstate;
4798 struct tmode_lstate *lstate;
4799 struct ccb_hdr_slist *list;
4800 cam_status status;
4801
4802 status = ahc_find_tmode_devs(ahc, sim, abort_ccb, &tstate,
4803 &lstate, TRUE);
4804
4805 if (status != CAM_REQ_CMP) {
4806 ccb->ccb_h.status = status;
4807 break;
4808 }
4809
4810 if (abort_ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO)
4811 list = &lstate->accept_tios;
4812 else if (abort_ccb->ccb_h.func_code == XPT_IMMED_NOTIFY)
4813 list = &lstate->immed_notifies;
4814 else
4815 list = NULL;
4816
4817 if (list != NULL) {
4818 struct ccb_hdr *curelm;
4819 int found;
4820
4821 curelm = SLIST_FIRST(list);
4822 found = 0;
4823 if (curelm == &abort_ccb->ccb_h) {
4824 found = 1;
4825 SLIST_REMOVE_HEAD(list, sim_links.sle);
4826 } else {
4827 while(curelm != NULL) {
4828 struct ccb_hdr *nextelm;
4829
4830 nextelm =
4831 SLIST_NEXT(curelm, sim_links.sle);
4832
4833 if (nextelm == &abort_ccb->ccb_h) {
4834 found = 1;
4835 SLIST_NEXT(curelm,
4836 sim_links.sle) =
4837 SLIST_NEXT(nextelm,
4838 sim_links.sle);
4839 break;
4840 }
4841 curelm = nextelm;
4842 }
4843 }
4844
4845 if (found)
4846 abort_ccb->ccb_h.status = CAM_REQ_ABORTED;
4847 else
4848 ccb->ccb_h.status = CAM_PATH_INVALID;
4849 break;
4850 }
4851 /* FALLTHROUGH */
4852 }
4853 case XPT_SCSI_IO:
4854 /* XXX Fully implement the hard ones */
4855 ccb->ccb_h.status = CAM_UA_ABORT;
4856 break;
4857 default:
4858 ccb->ccb_h.status = CAM_REQ_INVALID;
4859 break;
4860 }
4861 xpt_done(ccb);
4862}
4863
4661/*
4662 * Abort all SCBs that match the given description (target/channel/lun/tag),
4663 * setting their status to the passed in status if the status has not already
4664 * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer
4665 * is paused before it is called.
4666 */
4667static int
4668ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,

--- 539 unchanged lines hidden ---
4864/*
4865 * Abort all SCBs that match the given description (target/channel/lun/tag),
4866 * setting their status to the passed in status if the status has not already
4867 * been modified from CAM_REQ_INPROG. This routine assumes that the sequencer
4868 * is paused before it is called.
4869 */
4870static int
4871ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,

--- 539 unchanged lines hidden ---