static int32 scsi_int_dispatch(void *data) { BusLogic *bl = (BusLogic *) data; BL_CCB32 *bl_ccb; uchar intstat = inb(BL_INT_REG); #if BOOT #else if(!(intstat & BL_INT_INTV)) return B_UNHANDLED_INTERRUPT; #endif if(intstat & BL_INT_CMDC) { bl->done = 1; #ifdef VERBOSE_IRQ kprintf("buslogic_irq: Command Complete\n"); #endif } if(intstat & BL_INT_RSTS) { kprintf("buslogic_irq: BUS RESET\n"); } /* have we got mail? */ if(intstat & BL_INT_IMBL) { while(bl->in_boxes[bl->in_nextbox].completion_code) { bl_ccb = (BL_CCB32 *) PhysToVirt(unLE(bl->in_boxes[bl->in_nextbox].ccb_phys)); #ifdef VERBOSE_IRQ kprintf("buslogic_irq: CCB %08x (%08x) done, cc=0x%02x\n", unLE(bl->in_boxes[bl->in_nextbox].ccb_phys), (uint32) bl_ccb, bl->in_boxes[bl->in_nextbox].completion_code); #endif release_sem_etc(bl_ccb->done, 1, B_DO_NOT_RESCHEDULE); bl->in_boxes[bl->in_nextbox].completion_code = 0; bl->in_nextbox++; if(bl->in_nextbox == bl->box_count) bl->in_nextbox = 0; } } /* acknowledge the irq */ outb(BL_CONTROL_REG, BL_CONTROL_RINT); return B_HANDLED_INTERRUPT; }
/* specified by XferOffset. */ USHORT CopyToSGList (void FAR *Buffer, ULONG Count, PSCATGATENTRY pSGList, USHORT cSGList, ULONG XferOffset) { ULONG ppXferBuf; ULONG XferBufLen; USHORT XferLength; void far* VirtAddr; while ((cSGList)&&(pSGList->XferBufLen<=XferOffset)) { /* Seek into the scatgat list */ XferOffset-=(pSGList++)->XferBufLen; cSGList--; } XferBufLen= 0; while (Count) { if (!XferBufLen) /* Need to use next SG entry */ { if (!(cSGList--)) /* We run out of SG list elements */ return IOERR_CMD_SGLIST_BAD; ppXferBuf= pSGList->ppXferBuf+ XferOffset; XferBufLen= pSGList->XferBufLen- XferOffset; pSGList++; XferOffset= 0; } XferLength= 32768; /* To fit in USHORT */ if (Count<XferLength) XferLength= Count; if (XferBufLen<XferLength) XferLength= XferBufLen; if (!(VirtAddr= PhysToVirt(ppXferBuf,XferLength))) { ENABLE return IOERR_CMD_SGLIST_BAD; } memcpy (VirtAddr,Buffer,XferLength); ENABLE ppXferBuf+= XferLength; ((char far *)Buffer)+= XferLength; Count-= XferLength; XferBufLen-= XferLength; }
//-------------------------------------------------------------------------- static bool is_kernpage_used(ea_t ea, uint *size) { // via pagetable at 0xfffd0000 // fedcba9876543210fedcba9876543210 // sssssssbbbbbbbbbpppp............ int ixPage = (ea >> 20) & 0xFFF; // first level page table (uncached) (2nd half is r/o) int dwEntry = ((DWORD*)0xFFFD0000)[ixPage]; *size = (1 << 20); if ( (dwEntry & 3) == 2 ) { // section descriptor return true; } else if ( (dwEntry & 0xfffff) == 0 ) { return false; } else if ( (dwEntry & 3) == 1 ) { *size = (1 << 12); // coarse page table entry int phys_2nd_tlb = ea & ~0x3f; int virt_2nd_tlb = PhysToVirt(phys_2nd_tlb); if ( virt_2nd_tlb == 0 ) return false; int ix2ndPage = (ea>>12) & 0xff; int dw2ndEntry = ((DWORD*)virt_2nd_tlb)[ix2ndPage]; if ( (dw2ndEntry & 3) ==1 ) { // large page return true; } else if ( (dw2ndEntry & 3) == 2 ) { // small page return true; } return false; }