📄 blockio.c
字号:
do { if (bp->b_unit == dsk) bp->b_flag = 0; bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf));}/* *//* Flush all buffers for a disk *//* *//* returns: *//* TRUE on success *//* */BOOL flush_buffers(REG COUNT dsk){ struct buffer FAR *bp = firstbuf; REG BOOL ok = TRUE; bp = firstbuf; do { if (bp->b_unit == dsk) if (!flush1(bp)) ok = FALSE; bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf)); return ok;}/* *//* Write one disk buffer *//* */STATIC BOOL flush1(struct buffer FAR * bp){/* All lines with changes on 9/4/00 by BER marked below */ UWORD result; /* BER 9/4/00 */ if ((bp->b_flag & (BFR_VALID | BFR_DIRTY)) == (BFR_VALID | BFR_DIRTY)) { /* BER 9/4/00 */ result = dskxfer(bp->b_unit, bp->b_blkno, bp->b_buffer, 1, DSKWRITE); if (bp->b_flag & BFR_FAT) { UWORD b_copies = bp->b_copies; ULONG blkno = bp->b_blkno;#ifdef WITHFAT32 ULONG b_offset = bp->b_offset; if (b_offset == 0) /* FAT32 FS */ b_offset = bp->b_dpbp->dpb_xfatsize;#else UWORD b_offset = bp->b_offset;#endif while (--b_copies > 0) { blkno += b_offset; /* BER 9/4/00 */ result = dskxfer(bp->b_unit, blkno, bp->b_buffer, 1, DSKWRITE); } } } else result = 0; /* This negates any error code returned in result...BER */ /* and 0 returned, if no errors occurred - tom */ bp->b_flag &= ~BFR_DIRTY; /* even if error, mark not dirty */ if (result != 0) /* otherwise system has trouble */ bp->b_flag &= ~BFR_VALID; /* continuing. */ return (TRUE); /* Forced to TRUE...was like this before dskxfer() */ /* returned error codes...BER */}/* *//* Write all disk buffers *//* */BOOL flush(void){ REG struct buffer FAR *bp = firstbuf; REG BOOL ok; ok = TRUE; do { if (!flush1(bp)) ok = FALSE; bp->b_flag &= ~BFR_VALID; bp = b_next(bp); } while (FP_OFF(bp) != FP_OFF(firstbuf)); network_redirector(REM_FLUSHALL); return (ok);}/************************************************************************//* *//* Device Driver Interface Functions *//* *//************************************************************************//* *//* Transfer one or more blocks to/from disk *//* */UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, COUNT mode){ register struct dpb FAR *dpbp = get_dpb(dsk); if (dpbp == NULL) { return 0x0201; /* illegal command */ }#if TOM#define KeyboardShiftState() (*(BYTE FAR *)(MK_FP(0x40,0x17))) if (KeyboardShiftState() & 0x01) { printf("dskxfer:%s %x - %lx %u\n", mode == DSKWRITE ? "write" : "read", dsk, blkno, numblocks); if ((KeyboardShiftState() & 0x03) == 3) dumpBufferCache(); }#endif for (;;) { IoReqHdr.r_length = sizeof(request); IoReqHdr.r_unit = dpbp->dpb_subunit; switch (mode) { case DSKWRITE: if (verify_ena) { IoReqHdr.r_command = C_OUTVFY; break; } /* else fall through */ case DSKWRITEINT26: IoReqHdr.r_command = C_OUTPUT; break; case DSKREADINT25: case DSKREAD: IoReqHdr.r_command = C_INPUT; break; default: return 0x0100; /* illegal command */ } IoReqHdr.r_status = 0; IoReqHdr.r_meddesc = dpbp->dpb_mdb; IoReqHdr.r_count = numblocks; if ((dpbp->dpb_device->dh_attr & ATTR_HUGE) || blkno >= MAXSHORT) { IoReqHdr.r_start = HUGECOUNT; IoReqHdr.r_huge = blkno; } else IoReqHdr.r_start = (UWORD)blkno; /* * Some drivers normalise transfer address so HMA transfers are disastrous! * Then transfer block through xferbuf (DiskTransferBuffer doesn't work!) * (But this won't work for multi-block HMA transfers... are there any?) */ if (FP_SEG(buf) >= 0xa000 && numblocks == 1 && bufloc != LOC_CONV) { IoReqHdr.r_trans = deblock_buf; if (mode == DSKWRITE) fmemcpy(deblock_buf, buf, SEC_SIZE); execrh((request FAR *) & IoReqHdr, dpbp->dpb_device); if (mode == DSKREAD) fmemcpy(buf, deblock_buf, SEC_SIZE); } else { IoReqHdr.r_trans = (BYTE FAR *) buf; execrh((request FAR *) & IoReqHdr, dpbp->dpb_device); } if ((IoReqHdr.r_status & (S_ERROR | S_DONE)) == S_DONE) break; /* INT25/26 (_SEEMS_ TO) return immediately with 0x8002, if drive is not online,... normal operations (DIR) wait for ABORT/RETRY other condition codes not tested */ if (mode >= DSKWRITEINT26) return (IoReqHdr.r_status); loop: switch (block_error(&IoReqHdr, dpbp->dpb_unit, dpbp->dpb_device, mode)) { case ABORT: case FAIL: return (IoReqHdr.r_status); case RETRY: continue; case CONTINUE: break; default: goto loop; } break; } /* retry loop *//* *** Changed 9/4/00 BER */ return 0; /* Success! Return 0 for a successful operation. *//* End of change */}/* this removes any (additionally allocated) buffers from the HMA buffer chain, because they get allocated to the 'user'*/ void AllocateHMASpace (size_t lowbuffer, size_t highbuffer){ REG struct buffer FAR *bp = firstbuf; int n; if (FP_SEG(bp) != 0xffff) return; n = LoL_nbuffers; do { /* check if buffer intersects with requested area */ if (FP_OFF(bp) < highbuffer && FP_OFF(bp+1) > lowbuffer) { flush1(bp); /* unlink bp from buffer chain */ b_prev(bp)->b_next = bp->b_next; b_next(bp)->b_prev = bp->b_prev; if (FP_OFF(bp) == FP_OFF(firstbuf)) firstbuf = b_next(bp); LoL_nbuffers--; } bp = b_next(bp); } while (--n);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -