} else if ((resid_sgptr & ~SG_PTR_MASK) != 0) { panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
next_scb = &scb_data->scbarray[scb_data->numscbs];  sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);  if (sg_map == NULL) return; bzero(sg_map, sizeof(struct sg_map_node));  if (ahc_createdmamem(ahc, PAGE_SIZE, &sg_map->sg_dmamap, (caddr_t *)&sg_map->sg_vaddr, &sg_map->sg_physaddr, &sg_map->sg_dmasegs, &sg_map->sg_nseg, "SG space") < 0) { free(sg_map, M_DEVBUF); return; }  SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);  segs = sg_map->sg_vaddr; physaddr = sg_map->sg_physaddr;  newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));  for (i = 0; scb_data->numscbs < AHC_SCB_MAX && i < newcount; i++) { int error;  next_scb->sg_list = segs;  next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg); next_scb->flags = SCB_FREE;   dma_flags = ((ahc->chip & AHC_VL) !=0) ? BUS_DMA_NOWAIT|ISABUS_DMA_32BIT : BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW;  error = bus_dmamap_create(ahc->sc_dmat, AHC_MAXTRANSFER_SIZE, AHC_NSEG, MAXBSIZE, 0, dma_flags, &next_scb->dmamap); if (error !=0) break;  next_scb->hscb = &scb_data->hscbs[scb_data->numscbs]; next_scb->hscb->tag = ahc->scb_data->numscbs; next_scb->hscb->cmdstore_busaddr = ahc_hscb_busaddr(ahc, next_scb->hscb->tag) + offsetof(struct hardware_scb, cmdstore); next_scb->hscb->cmdstore_busaddr = htole32(next_scb->hscb->cmdstore_busaddr); SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, next_scb, links); segs += AHC_NSEG; physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg)); next_scb++; ahc->scb_data->numscbs++; } }  #ifdef AHC_DUMP_SEQ STATIC void ahc_dumpseq(ahc) struct ahc_softc* ahc; { int i; int max_prog;  if ((ahc->chip & AHC_BUS_MASK) < AHC_PCI) max_prog = 448; else if ((ahc->features & AHC_ULTRA2) != 0) max_prog = 768; else max_prog = 512;  ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); ahc_outb(ahc, SEQADDR0, 0); ahc_outb(ahc, SEQADDR1, 0); for (i = 0; i < max_prog; i++) { u_int8_t ins_bytes[4];  ahc_insb(ahc, SEQRAM, ins_bytes, 4); printf("0x%08x\n", ins_bytes[0] << 24 | ins_bytes[1] << 16 | ins_bytes[2] << 8 | ins_bytes[3]); } } #endif  STATIC void ahc_loadseq(ahc) struct ahc_softc* ahc; { struct patch *cur_patch; int i; int downloaded; int skip_addr; u_int8_t download_consts[4];   #if 0  download_consts[TMODE_NUMCMDS] = ahc->num_targetcmds; #endif  cur_patch = patches; downloaded = 0; skip_addr = 0; ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM); ahc_outb(ahc, SEQADDR0, 0); ahc_outb(ahc, SEQADDR1, 0);  for (i = 0; i < sizeof(seqprog)/4; i++) { if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {  continue; } ahc_download_instr(ahc, i, download_consts); downloaded++; } ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE); restart_sequencer(ahc);  if (bootverbose) printf(" %d instructions downloaded\n", downloaded); }  STATIC int ahc_check_patch(ahc, start_patch, start_instr,skip_addr) struct ahc_softc *ahc; struct patch **start_patch; int start_instr; int *skip_addr; { struct	patch *cur_patch; struct	patch *last_patch; int	num_patches;  num_patches = sizeof(patches)/sizeof(struct patch); last_patch = &patches[num_patches]; cur_patch = *start_patch;  while (cur_patch < last_patch && start_instr == cur_patch->begin) {  if (cur_patch->patch_func(ahc) == 0) {   *skip_addr = start_instr + cur_patch->skip_instr; cur_patch += cur_patch->skip_patch; } else {  cur_patch++; } }  *start_patch = cur_patch; if (start_instr < *skip_addr)  return (0);  return (1); }  STATIC void ahc_download_instr(ahc, instrptr, dconsts) struct ahc_softc *ahc; int instrptr; u_int8_t *dconsts; { union	ins_formats instr; struct	ins_format1 *fmt1_ins; struct	ins_format3 *fmt3_ins; u_int	opcode;   instr = *(union ins_formats*)&seqprog[instrptr * 4];  instr.integer = le32toh(instr.integer);  fmt1_ins = &instr.format1; fmt3_ins = NULL;   opcode = instr.format1.opcode; switch (opcode) { case AIC_OP_JMP: case AIC_OP_JC: case AIC_OP_JNC: case AIC_OP_CALL: case AIC_OP_JNE: case AIC_OP_JNZ: case AIC_OP_JE: case AIC_OP_JZ: { struct patch *cur_patch; int address_offset; u_int address; int skip_addr; int i;  fmt3_ins = &instr.format3; address_offset = 0; address = fmt3_ins->address; cur_patch = patches; skip_addr = 0;  for (i = 0; i < address;) {  ahc_check_patch(ahc, &cur_patch, i, &skip_addr);  if (skip_addr > i) { int end_addr;  end_addr = MIN(address, skip_addr); address_offset += end_addr - i; i = skip_addr; } else { i++; } } address -= address_offset; fmt3_ins->address = address;  } case AIC_OP_OR: case AIC_OP_AND: case AIC_OP_XOR: case AIC_OP_ADD: case AIC_OP_ADC: case AIC_OP_BMOV: if (fmt1_ins->parity != 0) { fmt1_ins->immediate = dconsts[fmt1_ins->immediate]; } fmt1_ins->parity = 0;  case AIC_OP_ROL: if ((ahc->features & AHC_ULTRA2) != 0) { int i, count;   for (i = 0, count = 0; i < 31; i++) { u_int32_t mask;  mask = 0x01 << i; if ((instr.integer & mask) != 0) count++; } if ((count & 0x01) == 0) instr.format1.parity = 1; } else {  if (fmt3_ins != NULL) { instr.integer = fmt3_ins->immediate | (fmt3_ins->source << 8) | (fmt3_ins->address << 16) |	(fmt3_ins->opcode << 25); } else { instr.integer = fmt1_ins->immediate | (fmt1_ins->source << 8) | (fmt1_ins->destination << 16) |	(fmt1_ins->ret << 24) |	(fmt1_ins->opcode << 25); } } instr.integer = htole32(instr.integer); ahc_outsb(ahc, SEQRAM, instr.bytes, 4); break; default: panic("Unknown opcode encountered in seq program"); break; } }  STATIC void ahc_set_recoveryscb(ahc, scb) struct ahc_softc *ahc; struct scb *scb; {  if ((scb->flags & SCB_RECOVERY_SCB) == 0) { struct scb *scbp;  scb->flags |= SCB_RECOVERY_SCB;   ahc->queue_blocked = 1;   scbp = ahc->pending_scbs.lh_first; while (scbp != NULL) { timeout_del(&scbp->xs->stimeout); scbp = scbp->pend_links.le_next; } } }  STATIC void ahc_timeout(void *arg) { struct	scb *scb; struct	ahc_softc *ahc; int	s, found; u_int	last_phase; int	target; int	lun; int	i; char	channel;  scb = (struct scb *)arg; ahc = (struct ahc_softc *)scb->xs->sc_link->adapter_softc;  s = splbio();   do { ahc_intr(ahc); pause_sequencer(ahc); } while (ahc_inb(ahc, INTSTAT) & INT_PEND);  if ((scb->flags & SCB_ACTIVE) == 0) {  printf("Timedout SCB handled by another timeout\n"); unpause_sequencer(ahc); splx(s); return; }  target = SCB_TARGET(scb); channel = SCB_CHANNEL(scb); lun = SCB_LUN(scb);  sc_print_addr(scb->xs->sc_link); printf("SCB 0x%x - timed out ", scb->hscb->tag);  last_phase = ahc_inb(ahc, LASTPHASE);  for (i = 0; i < num_phases; i++) { if (last_phase == phase_table[i].phase) break; } printf("%s", phase_table[i].phasemsg);  printf(", SEQADDR == 0x%x\n", ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); #if 0 printf("SSTAT1 == 0x%x\n", ahc_inb(ahc, SSTAT1)); printf("SSTAT3 == 0x%x\n", ahc_inb(ahc, SSTAT3)); printf("SCSIPHASE == 0x%x\n", ahc_inb(ahc, SCSIPHASE)); printf("SCSIRATE == 0x%x\n", ahc_inb(ahc, SCSIRATE)); printf("SCSIOFFSET == 0x%x\n", ahc_inb(ahc, SCSIOFFSET)); printf("SEQ_FLAGS == 0x%x\n", ahc_inb(ahc, SEQ_FLAGS)); printf("SCB_DATAPTR == 0x%x\n", ahc_inb(ahc, SCB_DATAPTR) | ahc_inb(ahc, SCB_DATAPTR + 1) << 8 | ahc_inb(ahc, SCB_DATAPTR + 2) << 16 | ahc_inb(ahc, SCB_DATAPTR + 3) << 24); printf("SCB_DATACNT == 0x%x\n", ahc_inb(ahc, SCB_DATACNT) | ahc_inb(ahc, SCB_DATACNT + 1) << 8 | ahc_inb(ahc, SCB_DATACNT + 2) << 16); printf("SCB_SGCOUNT == 0x%x\n", ahc_inb(ahc, SCB_SGCOUNT)); printf("CCSCBCTL == 0x%x\n", ahc_inb(ahc, CCSCBCTL)); printf("CCSCBCNT == 0x%x\n", ahc_inb(ahc, CCSCBCNT)); printf("DFCNTRL == 0x%x\n", ahc_inb(ahc, DFCNTRL)); printf("DFSTATUS == 0x%x\n", ahc_inb(ahc, DFSTATUS)); printf("CCHCNT == 0x%x\n", ahc_inb(ahc, CCHCNT)); if (scb->sg_count > 0) { for (i = 0; i < scb->sg_count; i++) { printf("sg[%d] - Addr 0x%x : Length %d\n", i, le32toh(scb->sg_list[i].addr), le32toh(scb->sg_list[i].len)); } } #endif if (scb->flags & (SCB_DEVICE_RESET|SCB_ABORT)) {  bus_reset: ahcsetccbstatus(scb->xs, XS_TIMEOUT); found = ahc_reset_channel(ahc, channel, TRUE); printf("%s: Issued Channel %c Bus Reset. " "%d SCBs aborted\n", ahc_name(ahc), channel, found);
ahc_calc_residual(struct scb *scb){	struct hardware_scb *hscb;	struct status_pkt *spkt;	uint32_t sgptr;	uint32_t resid_sgptr;	uint32_t resid;	/*	 * 5 cases.	 * 1) No residual.	 *    SG_RESID_VALID clear in sgptr.	 * 2) Transferless command	 * 3) Never performed any transfers.	 *    sgptr has SG_FULL_RESID set.	 * 4) No residual but target did not	 *    save data pointers after the	 *    last transfer, so sgptr was	 *    never updated.	 * 5) We have a partial residual.	 *    Use residual_sgptr to determine	 *    where we are.	 */	hscb = scb->hscb;	sgptr = ahc_le32toh(hscb->sgptr);	if ((sgptr & SG_RESID_VALID) == 0)		/* Case 1 */		return;	sgptr &= ~SG_RESID_VALID;	if ((sgptr & SG_LIST_NULL) != 0)		/* Case 2 */		return;	spkt = &hscb->shared_data.status;	resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);	if ((sgptr & SG_FULL_RESID) != 0) {		/* Case 3 */		resid = ahc_get_transfer_length(scb);	} else if ((resid_sgptr & SG_LIST_NULL) != 0) {		/* Case 4 */		return;	} else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {		panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);	} else {		struct ahc_dma_seg *sg;		/*		 * Remainder of the SG where the transfer		 * stopped.  		 */		resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;		sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);		/* The residual sg_ptr always points to the next sg */		sg--;		/*		 * Add up the contents of all residual		 * SG segments that are after the SG where		 * the transfer stopped.		 */		while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {			sg++;			resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;		}	}	if ((scb->flags & SCB_SENSE) == 0)		ahc_set_residual(scb, resid);	else		ahc_set_sense_residual(scb, resid);#ifdef AHC_DEBUG	if (ahc_debug & AHC_SHOWMISC) {		ahc_print_path(scb->ahc_softc, scb);		printf("Handled Residual of %d bytes\n", resid);	}#endif}