Annotation of driverkit/notes/FloppyRw, revision 1.1.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.