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 --- |