Annotation of driverkit/notes/FloppyRw, revision 1.1

1.1     ! root        1: #define KVM_PUNT       1       
        !             2: #define REQUIRE_SECT_ALIGN     1       /* */
        !             3: 
        !             4: static boolean_t fd_setup_rw_req(fd_volume_t fvp, 
        !             5:        boolean_t bad_block_map)        /* TRUE = check for remapping */
        !             6: {
        !             7:        /* input:  fvp->start_sect
        !             8:         *         fvp->bytes_to_go
        !             9:         *         fvp->start_addrs
        !            10:         *         fvp->io_flags
        !            11:         *         fvp->dev_ioreq.pmap
        !            12:         *         fvp->dev_ioreq.map
        !            13:         *         fvp->format_info
        !            14:         * output: fvp->current_sect
        !            15:         *         fvp->current_byte_cnt
        !            16:         *         fvp->current_addrs
        !            17:         *         fvp->dev_ioreq
        !            18:         * 
        !            19:         * This routine determines the largest "safe" I/O which can be
        !            20:         * performed starting at fvp->start_sect, up to a max of 
        !            21:         * fvp->bytes_to_go bytes. The bad block table will only be consulted
        !            22:         * if bad_block_map is also TRUE.
        !            23:         *
        !            24:         * No I/O is allowed to go past a track boundary.
        !            25:         *
        !            26:         * Short writes (less than one sector) result in user data being 
        !            27:         * copied to *fvp->sect_buf, memory for which is allocated here.
        !            28:         * DMA occurs out of this buffer. The buffer must be freed upon I/O
        !            29:         * complete. 
        !            30:         *
        !            31:         * Parameters describing the resulting "safe" I/O are placed in
        !            32:         * fvp->current_sect and fvp->current_byte_cnt. An fd_rw_cmd is then
        !            33:         * generated and placed in fvp->dev_ioreq.cmd_blk[].
        !            34:         *
        !            35:         * Returns TRUE if mapping occurred.
        !            36:         */
        !            37:        struct fd_rw_cmd start_rw_cmd;          /* first sector, phys params */
        !            38:        struct fd_format_info *fip = &fvp->format_info;
        !            39:        u_int sect_size = fip->sectsize_info.sect_size;
        !            40:        int num_sects = howmany(fvp->bytes_to_go, sect_size);
        !            41:        int bytes_to_xfr;
        !            42:        caddr_t start_addrs;
        !            43:        
        !            44:        XDBG(("fd_setup_rw_req: start_sect = %d\n", fvp->start_sect));
        !            45:        /*
        !            46:         * See if we'll wrap past a track boundary. Max sector number on
        !            47:         * a track is sects_per_trk, NOT sects_per_trk-1...
        !            48:         */
        !            49:        fd_log_2_phys(fvp, fvp->start_sect, &start_rw_cmd);
        !            50:        if((start_rw_cmd.sector + num_sects) >
        !            51:          (fip->sectsize_info.sects_per_trk+1)) {
        !            52:                num_sects = fip->sectsize_info.sects_per_trk -
        !            53:                    start_rw_cmd.sector + 1;
        !            54:                bytes_to_xfr = num_sects * sect_size;
        !            55:                XDBG(("fd_setup_rw_req: track wrap: num_sects = %d\n", 
        !            56:                        num_sects));
        !            57:        }
        !            58:        else {
        !            59:                /*
        !            60:                 * The whole I/O fits on one track.
        !            61:                 */
        !            62:                bytes_to_xfr = fvp->bytes_to_go;
        !            63:        }
        !            64:        /*
        !            65:         * See if we have to deal with a partial sector.
        !            66:         */
        !            67:        start_addrs = fvp->start_addrs;
        !            68:        fvp->padded_byte_cnt = 0;       
        !            69: #ifdef REQUIRE_SECT_ALIGN
        !            70:        if(bytes_to_xfr & (sect_size - 1)) {
        !            71:                printf("fd%d: PARTIAL SECTOR I/O\n", fvp->volume_num);
        !            72:        }
        !            73: short_write_out:
        !            74: 
        !            75:        fvp->current_sect     = fvp->start_sect;
        !            76:        fvp->current_byte_cnt = bytes_to_xfr;
        !            77:        fvp->current_addrs    = start_addrs;
        !            78:        fd_gen_rw_cmd(fvp,
        !            79:                &fvp->dev_ioreq,
        !            80:                fvp->current_sect,
        !            81:                fvp->current_byte_cnt,
        !            82:                fvp->current_addrs,
        !            83:                fvp->io_flags & FVIOF_READ);
        !            84:        return(FALSE);
        !            85:        
        !            86: } /* fd_setup_rw_req() */
        !            87: 
        !            88: /*
        !            89:  * generate a write or read command in *fdiop (No I/O).
        !            90:  */
        !            91: static void fd_gen_rw_cmd(fd_volume_t fvp,
        !            92:        fd_ioreq_t fdiop,
        !            93:        u_int sector,
        !            94:        u_int byte_count,
        !            95:        caddr_t dma_addrs,
        !            96:        int read)               /* non-zero ==> read */
        !            97: {
        !            98:        struct fd_rw_cmd *cmdp = (struct fd_rw_cmd *)fdiop->cmd_blk;
        !            99:        struct fd_format_info *fip = &fvp->format_info;
        !           100:        
        !           101:        XADDBG(("fd_gen_rw_cmd: sector 0x%x byte_count 0x%x read = %d\n",
        !           102:                sector, byte_count, read));
        !           103:        bzero(cmdp, SIZEOF_RW_CMD);
        !           104:        fd_log_2_phys(fvp, sector, cmdp);       /* assign track, head, sect */
        !           105:        cmdp->mt = 0;                           /* multitrack - always false */
        !           106:        cmdp->mfm = fip->density_info.mfm;
        !           107:        cmdp->opcode = read ? FCCMD_READ : FCCMD_WRITE;
        !           108:        cmdp->hds = cmdp->head;
        !           109:        /*
        !           110:         * controller thread writes drive_sel.
        !           111:         */
        !           112:        cmdp->sector_size = fip->sectsize_info.n;
        !           113:        /*
        !           114:         * eot = the number of the LAST sector to be read/written.
        !           115:         */
        !           116:        cmdp->eot = cmdp->sector + howmany(byte_count,
        !           117:                                           fip->sectsize_info.sect_size) - 1;
        !           118:        cmdp->gap_length = fip->sectsize_info.rw_gap_length;
        !           119:        cmdp->dtl = 0xff;
        !           120:        
        !           121:        fdiop->density = fip->density_info.density;
        !           122:        fdiop->timeout = TO_RW;
        !           123:        fdiop->command = FDCMD_CMD_XFR;
        !           124:        fdiop->num_cmd_bytes = SIZEOF_RW_CMD;
        !           125:        fdiop->addrs = dma_addrs;
        !           126:        fdiop->byte_count = byte_count;
        !           127:        fdiop->num_stat_bytes = SIZEOF_RW_STAT;
        !           128:        if(read)
        !           129:                fdiop->flags |= FD_IOF_DMA_RD;
        !           130:        else
        !           131:                fdiop->flags &= ~FD_IOF_DMA_RD;
        !           132:        
        !           133: } /* fd_gen_rw_cmd() */
        !           134: 
        !           135: /*
        !           136:  * convert logical sector # into cylinder, head, sector. No range checking.
        !           137:  * Physical parameters are obtained from *fvp->labelp and fvp->sects_per_track.
        !           138:  *
        !           139:  * First sector on a track is sector 1.
        !           140:  */
        !           141: static void fd_log_2_phys(fd_volume_t fvp,
        !           142:        u_int sector,
        !           143:        struct fd_rw_cmd *cmdp)
        !           144: {
        !           145:        u_int track;
        !           146:        struct fd_format_info *fip = &fvp->format_info;
        !           147:        
        !           148:        ASSERT((fip->sectsize_info.sects_per_trk != 0) && 
        !           149:               (fip->disk_info.tracks_per_cyl != 0));   
        !           150:        track = sector / fip->sectsize_info.sects_per_trk;
        !           151:        cmdp->cylinder = track / fip->disk_info.tracks_per_cyl;
        !           152:        cmdp->head     = track % fip->disk_info.tracks_per_cyl;
        !           153:        cmdp->sector   = sector % fip->sectsize_info.sects_per_trk + 1;
        !           154:        XADDBG(("fd_log_2_phys: lsect 0x%x; cyl 0x%x  head 0x%x  sector "
        !           155:                "0x%x\n", sector, cmdp->cylinder, cmdp->head, cmdp->sector-1));
        !           156: }
        !           157: 
        !           158: ........................
        !           159: 
        !           160: what we really want:
        !           161: 
        !           162: /*
        !           163:  * Common r/w routine. The following fdBuf fields are required:
        !           164:  *     block
        !           165:  *     blockCnt
        !           166:  *     buf
        !           167:  *     client
        !           168:  *     pending
        !           169:  *
        !           170:  * block and blockCnt are assumed to be already adjusted for overflow.
        !           171:  */
        !           172: - (ioReturn_t)fdRwCommon       : (fdBuf_t *)fdBuf
        !           173: {
        !           174:        int currentBlock = fdBuf->block;
        !           175:        int blocksToGo = fdBuf->blockCnt;
        !           176:        char *currentBuf = fdBuf->buf;
        !           177:        int currentBlockCnt;
        !           178:        fdIoReq_t fdIoReq;
        !           179:        ioReturn_t rtn;
        !           180:        int block_size = [self getBlockSize];
        !           181:        boolean_t readFlag = fdBuf->command == FDC_READ ? TRUE : FALSE;
        !           182:        
        !           183:        xpr_fd("fdRwCommon: block 0x%x count 0x%x\n", 
        !           184:                fdBuf->block, fdBuf->BlockCnt, 3,4,5);
        !           185:        
        !           186:        /*
        !           187:         * We never cross a track boundary while reading and writing. This
        !           188:         * loop is executed once for each segment.
        !           189:         */
        !           190:        while(blocksToGo) {
        !           191:        
        !           192:                /*
        !           193:                 * Set up controller command block for current segment.
        !           194:                 */
        !           195:                currentBlockCnt = [self rwBlockCount:currentBlock
        !           196:                        blocksToGo:blocksToGo];
        !           197:                [self fdGenRwCmd:currentBlock
        !           198:                        blockCount:currentBlockCnt
        !           199:                        fdIoReq:&fdIoReq
        !           200:                        read:readFlag];
        !           201:                fdIoReq->command = FDCMD_CMD_XFR;
        !           202:                fdIoReq->addrs = currentBuf;
        !           203:                fdIoReq->byte_count = currentBlockCnt * block_size;
        !           204:                rtn = [self fdSendCmd:&fdIoReq];
        !           205:                
        !           206:                /*
        !           207:                 * OK, what happened?
        !           208:                 */
        !           209:        }
        !           210: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.