Annotation of Examples/UNIX/Floppy/fdform.c, revision 1.1

1.1     ! root        1: /* fdform - Floppy format utility
        !             2:  *
        !             3:  *     usage:   fdform device [b=blocksize] [d=density] [g=gap3_length] 
        !             4:  *                             [n=num_cylinders]
        !             5:  *
        !             6:  *             blocksize must be 512 or 1024.
        !             7:  *             density is in Kbytes. Current legal values are 720, 1440,
        !             8:  *                     and 2880. Default is max density allowable for media.
        !             9:  *
        !            10:  *
        !            11:  *     You may freely copy, distribute and reuse the code in this example.
        !            12:  *     NeXT disclaims any warranty of any kind, expressed or implied, as to
        !            13:  *     its fitness for any particular use.
        !            14:  */
        !            15: 
        !            16: #import <fcntl.h>
        !            17: #import <stdio.h>
        !            18: #import <sys/types.h>
        !            19: #import <mach/mach.h>
        !            20: #import <bsd/dev/scsireg.h>
        !            21: /*
        !            22:  * m68k is worst case as far as alignment restrictions...
        !            23:  */
        !            24: #ifdef m68k
        !            25: #import <bsd/dev/m68k/dma.h>
        !            26: #endif m68k
        !            27: #import <sys/param.h>
        !            28: #import <signal.h>
        !            29: #import <bsd/dev/fd_extern.h>
        !            30: #import <libc.h>
        !            31: #import <stdlib.h>
        !            32: #import <sys/file.h>
        !            33: 
        !            34: void usage(char **argv);
        !            35: int format_disk(int fd, int live_fd, struct fd_format_info *finfop);
        !            36: int format_track(int fd, int cylinder, int head, 
        !            37:        struct fd_format_info *finfop);
        !            38: int recalibrate(int fd, struct fd_format_info *fip);
        !            39: int seek_com(int fd, int track, struct fd_format_info *finfop, int density);
        !            40: int do_ioc(int fd, fd_ioreq_t fdiop);
        !            41: int fd_rw(int fd,
        !            42:        int block,
        !            43:        int block_count,
        !            44:        u_char *addrs,
        !            45:        boolean_t read_flag,
        !            46:        struct fd_format_info *finfop);
        !            47: void format_abort();
        !            48: 
        !            49: #ifndef        TRUE
        !            50: #define TRUE   (1)
        !            51: #endif TRUE
        !            52: #ifndef        FALSE
        !            53: #define FALSE  (0)
        !            54: #endif FALSE
        !            55: 
        !            56: u_char                         *vfy_buf;
        !            57: struct format_data     *fdp;
        !            58: int                    cyls_to_format = 0;
        !            59: int                    fmt_gap3_length = -1;
        !            60: int                    fd;
        !            61: int                    live_fd;
        !            62: struct fd_format_info  format_info;
        !            63: 
        !            64: int main(int argc, char *argv[])
        !            65: {
        !            66:        int                     arg;
        !            67:        char                    ch;
        !            68:        int                     rtn;
        !            69:        kern_return_t           krtn;
        !            70:        int                     format_data_size;
        !            71:        struct fd_sectsize_info *ssip;
        !            72:        int                     density = FD_DENS_NONE;
        !            73:        int                     blocksize = 512;
        !            74:        
        !            75:        if(argc<2) 
        !            76:                usage(argv);
        !            77:        fd = open(argv[1], O_RDWR, 0);
        !            78:        if(fd <= 0) {
        !            79:                printf("Opening %s:\n", argv[1]);
        !            80:                perror("open");
        !            81:                exit(1);
        !            82:        }
        !            83:        
        !            84:        /*
        !            85:         * Open the live partition for read/verify.
        !            86:         */
        !            87:        argv[1][strlen(argv[1]) - 1] = 'b';
        !            88:        live_fd = open(argv[1], O_RDONLY, 0);
        !            89:        if(live_fd <= 0) {
        !            90:                printf("Opening %s:\n", argv[1]);
        !            91:                perror("open");
        !            92:                exit(1);
        !            93:        }
        !            94:        for(arg=2; arg<argc; arg++) {
        !            95:                ch = argv[arg][0];
        !            96:                switch(ch) {
        !            97:                    case 'd':
        !            98:                        density = atoi(&argv[arg][2]);
        !            99:                        switch(density) {
        !           100:                            case 720:
        !           101:                                density = FD_DENS_1;
        !           102:                                break;
        !           103:                            case 1440:
        !           104:                                density = FD_DENS_2;
        !           105:                                break;
        !           106:                            case 2880:
        !           107:                                density = FD_DENS_4;
        !           108:                                break;
        !           109:                            default:
        !           110:                                usage(argv);
        !           111:                        }
        !           112:                        break;
        !           113:                    case 'b':
        !           114:                        blocksize = atoi(&argv[arg][2]);
        !           115:                        if((blocksize != 512) && (blocksize != 1024))
        !           116:                                usage(argv);
        !           117:                        break;
        !           118:                        
        !           119:                    case 'g':
        !           120:                        fmt_gap3_length = atoi(&argv[arg][2]);
        !           121:                        break;
        !           122:                        
        !           123:                    case 'n':
        !           124:                        cyls_to_format = atoi(&argv[arg][2]);
        !           125:                        break;
        !           126:                        
        !           127:                    default:
        !           128:                        usage(argv);
        !           129:                }
        !           130:        }
        !           131:        /*
        !           132:         * find out what kind of disk is installed, then ensure that we
        !           133:         * haven't been asked to format a bogus density for this disk.
        !           134:         */
        !           135:        if(ioctl(fd, FDIOCGFORM, &format_info)) {
        !           136:                perror("ioctl(FDIOCGFORM)");
        !           137:                return(1);
        !           138:        }
        !           139:        if(density > format_info.disk_info.max_density) {
        !           140:                printf("\nMaximum Legal Density for this disk is ");
        !           141:                switch(format_info.disk_info.max_density) {
        !           142:                    case FD_DENS_1:
        !           143:                        printf("1 (720 KBytes formatted)\n");
        !           144:                        exit(1);
        !           145:                    case FD_DENS_2:
        !           146:                        printf("2 (1.44 MByte formatted)\n");
        !           147:                        exit(1);
        !           148:                    case FD_DENS_4:
        !           149:                        printf("4 (2.88 MByte formatted)\n");
        !           150:                        exit(1);
        !           151:                }
        !           152:        }
        !           153:        if(density == FD_DENS_NONE) 
        !           154:                density = format_info.disk_info.max_density;
        !           155: 
        !           156:        printf("Formatting disk %s: \n", argv[1]);
        !           157:        printf("    blocksize   = 0x%x\n", blocksize);
        !           158:        printf("    density     = ");
        !           159:        switch(density) {
        !           160:            case FD_DENS_1:
        !           161:                printf("720 KBytes\n");
        !           162:                break;
        !           163:            case FD_DENS_2:
        !           164:                printf("1.44 MByte\n");
        !           165:                break;
        !           166:            case FD_DENS_4:
        !           167:                printf("2.88 MByte\n");
        !           168:                break;
        !           169:        }       
        !           170:        /*
        !           171:         * If user hasn't specified gap length, use default provided by driver
        !           172:         */
        !           173:        if(fmt_gap3_length < 0)
        !           174:                fmt_gap3_length = format_info.sectsize_info.fmt_gap_length;
        !           175:        printf("    gap3 length = %d(d)\n", fmt_gap3_length);
        !           176: 
        !           177:        /*
        !           178:         * Generate a new format_info. Have the driver calculate physical 
        !           179:         * parameters based on sector size and density.  If we abort the 
        !           180:         * format for any reason, we'll mark the disk unformatted.
        !           181:         */
        !           182:        if(ioctl(fd, FDIOCSDENS, &density)) {
        !           183:                perror("ioctl(FDIOCSDENS)");
        !           184:                return(1);
        !           185:        }
        !           186:        if(ioctl(fd, FDIOCSSIZE, &blocksize)) {
        !           187:                perror("ioctl(FDIOCSSIZE)");
        !           188:                return(1);
        !           189:        }
        !           190: 
        !           191:        /*
        !           192:         * This returns all the current parameters, based on what we just
        !           193:         * told the driver.
        !           194:         */
        !           195:        if(ioctl(fd, FDIOCGFORM, &format_info)) {
        !           196:                perror("ioctl(FDIOCGFORM)");
        !           197:                format_abort();
        !           198:        }
        !           199:        
        !           200:        /*
        !           201:         * Get page-aligned buffers for all the reading and writing we'll 
        !           202:         * be doing.
        !           203:         */
        !           204:        ssip = &format_info.sectsize_info;
        !           205:        krtn = vm_allocate(task_self(), 
        !           206:                        (vm_address_t *)&vfy_buf,
        !           207:                        ssip->sects_per_trk * ssip->sect_size,
        !           208:                        TRUE);
        !           209:        if(krtn) {
        !           210:                printf("\n...Couldn't allocate track buffer\n");
        !           211:                format_abort();
        !           212:        }
        !           213:        format_data_size = sizeof(struct format_data) * ssip->sects_per_trk;
        !           214:        krtn = vm_allocate(task_self(), 
        !           215:                        (vm_address_t *)&fdp,
        !           216:                        format_data_size,
        !           217:                        TRUE);
        !           218:        if(krtn) {
        !           219:                printf("\n...Couldn't allocate Format data buffer\n");
        !           220:                format_abort();
        !           221:        }
        !           222: 
        !           223:        signal(SIGINT, format_abort);
        !           224:        if ((rtn = format_disk(fd, live_fd, &format_info)))
        !           225:            format_abort();
        !           226:        
        !           227:        printf("\n..Format Complete\n");
        !           228:        exit(0);
        !           229: }
        !           230: 
        !           231: void usage(char **argv) {
        !           232:        printf("usage: %s device [b=blocksize)] [d=density] [g=gap3_length] [n=num_cylinders]\n", argv[0]);
        !           233:        printf("       blocksize = 512 or 1024\n");
        !           234:        printf("       density = 720, 1440, 2880\n");
        !           235:        exit(1);
        !           236: }
        !           237: 
        !           238: void format_abort()
        !           239: {
        !           240:        int arg;
        !           241:        
        !           242:        /*
        !           243:         * ctl C or error abort; mark disk as unformatted.
        !           244:         */
        !           245:        arg = FD_DENS_NONE;
        !           246:        if(ioctl(fd, FDIOCSDENS, &arg)) {       /* unformatted */
        !           247:                perror("ioctl(FDIOCSDENS)");
        !           248:                exit(1);
        !           249:        }
        !           250:        printf("\n..Format Aborted\n");
        !           251:        exit(1);
        !           252: 
        !           253: }
        !           254: int format_disk(int fd, int live_fd, struct fd_format_info *finfop)
        !           255: {
        !           256:        int rtn;
        !           257:        int cylinder;
        !           258:        int head;
        !           259:        int vfy_block=0;
        !           260:        struct fd_sectsize_info *ssip = &finfop->sectsize_info;
        !           261:        
        !           262:        if(cyls_to_format == 0)
        !           263:                cyls_to_format = format_info.disk_info.num_cylinders;
        !           264:                
        !           265:        if ((rtn = recalibrate(fd, &format_info))) {
        !           266:                return(1);
        !           267:        }
        !           268:        for(cylinder=0; cylinder<cyls_to_format; cylinder++) {
        !           269:                for(head=0; 
        !           270:                    head<format_info.disk_info.tracks_per_cyl; 
        !           271:                    head++) {
        !           272:                        if ((rtn = format_track(fd, cylinder, head, finfop))) {
        !           273:                                printf("\n...Format track FAILED\n");
        !           274:                                printf("  cyl %d  head %d\n", cylinder, head);
        !           275:                                return(1);
        !           276:                        }
        !           277:                        /*
        !           278:                         * Read the whole track. No data verify; just rely on
        !           279:                         * CRC.
        !           280:                         */
        !           281:                        if(fd_rw(live_fd,
        !           282:                            vfy_block,
        !           283:                            ssip->sects_per_trk,
        !           284:                            vfy_buf,
        !           285:                            TRUE,
        !           286:                            finfop))
        !           287:                                return(1);
        !           288:                        vfy_block += ssip->sects_per_trk;
        !           289:                }
        !           290:                printf(".");   
        !           291:                fflush(stdout);
        !           292:        }
        !           293:        return(0);
        !           294: }
        !           295:  
        !           296: /*
        !           297:  * Format one track.
        !           298:  */
        !           299: int format_track(int fd, int cylinder, int head, struct fd_format_info *finfop)
        !           300: {
        !           301:        struct format_data *fdp_work;
        !           302:        int sector;
        !           303:        struct fd_ioreq ioreq;
        !           304:        struct fd_format_cmd *cmdp = (struct fd_format_cmd *)ioreq.cmd_blk;
        !           305:        int data_size;
        !           306:        int rtn=0;
        !           307:        struct fd_sectsize_info *ssip = &finfop->sectsize_info;
        !           308: 
        !           309:        data_size = sizeof(struct format_data) * ssip->sects_per_trk;
        !           310: 
        !           311:        /*
        !           312:         * Generate the data we'll DMA during the format track command.
        !           313:         * This consists if the headers for each sector on the cylinder.
        !           314:         */
        !           315:        fdp_work = fdp;
        !           316:        for(sector=1; sector<=ssip->sects_per_trk; sector++) {
        !           317:                fdp_work->cylinder = cylinder;
        !           318:                fdp_work->head = head;
        !           319:                fdp_work->sector = sector;
        !           320:                fdp_work->n = ssip->n;
        !           321:                fdp_work++;
        !           322:        }
        !           323:        if(seek_com(fd, cylinder * finfop->disk_info.tracks_per_cyl + head, 
        !           324:            finfop, finfop->density_info.density)) {
        !           325:                return(1);
        !           326:        }
        !           327:        usleep(20000);          /* head settling time - 20 ms (fixme) */
        !           328:        
        !           329:        /*
        !           330:         * Build a format command 
        !           331:         */
        !           332:        bzero(&ioreq, sizeof (struct fd_ioreq));
        !           333:        
        !           334:        ioreq.density = finfop->density_info.density;
        !           335:        ioreq.timeout = 5000;
        !           336:        ioreq.command = FDCMD_CMD_XFR;
        !           337:        ioreq.num_cmd_bytes = sizeof(struct fd_format_cmd);
        !           338:        ioreq.addrs = (caddr_t)fdp;
        !           339: #if    m68k
        !           340:        ioreq.byte_count = DMA_ENDALIGN(int, data_size);
        !           341: #else  m68k
        !           342:        ioreq.byte_count = data_size;
        !           343: #endif m68k
        !           344:        ioreq.num_stat_bytes = SIZEOF_RW_STAT;
        !           345:        ioreq.flags = FD_IOF_DMA_WR;
        !           346:        
        !           347:        cmdp->mfm           = finfop->density_info.mfm;
        !           348:        cmdp->opcode        = FCCMD_FORMAT;
        !           349:        cmdp->hds           = head;
        !           350:        cmdp->n             = ssip->n;
        !           351:        cmdp->sects_per_trk = ssip->sects_per_trk;
        !           352:        cmdp->gap_length    = fmt_gap3_length;
        !           353:        cmdp->filler_data   = 0x5a;
        !           354:        rtn = do_ioc(fd, &ioreq);
        !           355:        if(rtn) {
        !           356:                printf("\n...Format (cylinder %d head %d) Failed\n", 
        !           357:                        cylinder, head);
        !           358:        }
        !           359:        return(rtn);
        !           360: } /* format_track() */
        !           361: 
        !           362: int recalibrate(int fd, struct fd_format_info *fip) {
        !           363:        struct fd_ioreq ioreq;
        !           364:        struct fd_seek_cmd *cmdp = (struct fd_seek_cmd *)ioreq.cmd_blk;
        !           365:        int rtn=0;
        !           366:        
        !           367:        bzero(&ioreq, sizeof(struct fd_ioreq));
        !           368:        cmdp->opcode = FCCMD_RECAL;
        !           369:        ioreq.density = fip->density_info.density;
        !           370:        ioreq.timeout = 2000;
        !           371:        ioreq.command = FDCMD_CMD_XFR;
        !           372:        ioreq.num_cmd_bytes = sizeof(struct fd_recal_cmd);
        !           373:        ioreq.addrs = 0;
        !           374:        ioreq.byte_count = 0;
        !           375:        ioreq.num_stat_bytes = sizeof(struct fd_int_stat);
        !           376:        rtn = do_ioc(fd, &ioreq);
        !           377:        if(rtn) {
        !           378:                printf("\n...Recalibrate Failed\n");
        !           379:        }
        !           380:        return(rtn);
        !           381: }
        !           382: 
        !           383: int do_ioc(int fd, fd_ioreq_t fdiop)
        !           384: {      
        !           385:        int rtn=0;
        !           386:        
        !           387:        fdiop->status = FDR_SUCCESS;
        !           388:        if (ioctl(fd, FDIOCREQ, fdiop) < 0) {
        !           389:                perror("ioctl(FDIOCREQ)");
        !           390:                rtn = 1;
        !           391:                goto check_status;
        !           392:        }
        !           393:        if(fdiop->num_cmd_bytes != fdiop->cmd_bytes_xfr) {
        !           394:                printf("\n...Expected cmd byte count = 0x%x\n",
        !           395:                        fdiop->num_cmd_bytes);
        !           396:                printf("   received cmd byte count = 0x%x\n",
        !           397:                        fdiop->cmd_bytes_xfr);
        !           398:                rtn = 1;
        !           399:                goto check_status;
        !           400:        }
        !           401:        if(fdiop->num_stat_bytes != fdiop->stat_bytes_xfr) {
        !           402:                printf("\n...Expected status byte count = 0x%x\n", 
        !           403:                        fdiop->num_stat_bytes);
        !           404:                printf("   received status byte count = 0x%x\n", 
        !           405:                        fdiop->stat_bytes_xfr);
        !           406:                rtn = 1;
        !           407:                goto check_status;
        !           408:        }
        !           409:        if(fdiop->byte_count != fdiop->bytes_xfr) {
        !           410:                printf("\n...Expected byte count = 0x%x\n", fdiop->byte_count);
        !           411:                printf("   received byte count = 0x%x\n", fdiop->bytes_xfr);
        !           412:                rtn = 1;
        !           413:                goto check_status;
        !           414:        }
        !           415: check_status:
        !           416:        if(fdiop->status != FDR_SUCCESS) {
        !           417:                rtn = 1;
        !           418:                printf("\n...Unexpected status: %x\n", fdiop->status);
        !           419:        }
        !           420:        return(rtn);
        !           421: }
        !           422: 
        !           423: int seek_com(int fd, int track, struct fd_format_info *finfop, int density)
        !           424: {
        !           425:        struct fd_ioreq ioreq;
        !           426:        struct fd_seek_cmd *cmdp = (struct fd_seek_cmd *)ioreq.cmd_blk;
        !           427:        int rtn = 0;
        !           428:        
        !           429:        bzero(&ioreq, sizeof(struct fd_ioreq));
        !           430:        cmdp->opcode = FCCMD_SEEK;
        !           431:        cmdp->hds = track % finfop->disk_info.tracks_per_cyl;
        !           432:        cmdp->cyl = track / finfop->disk_info.tracks_per_cyl;
        !           433:        ioreq.timeout = 2000;
        !           434:        ioreq.density = density;
        !           435:        ioreq.command = FDCMD_CMD_XFR;
        !           436:        ioreq.num_cmd_bytes = SIZEOF_SEEK_CMD;
        !           437:        ioreq.num_stat_bytes = sizeof(struct fd_int_stat);
        !           438:        rtn = do_ioc(fd, &ioreq);
        !           439:        if(rtn) {
        !           440:                printf("\n...Seek (track %d) failed\n", track);
        !           441:        }
        !           442:        return(rtn);
        !           443: }
        !           444: 
        !           445: #define        USE_LIVE_IO     1
        !           446: 
        !           447: #if    USE_LIVE_IO
        !           448: 
        !           449: int fd_rw(int fd,
        !           450:        int block,
        !           451:        int block_count,
        !           452:        u_char *addrs,
        !           453:        boolean_t read_flag,
        !           454:        struct fd_format_info *finfop)
        !           455: {
        !           456:        int             rtn;
        !           457:        char            *read_str;
        !           458:        int             byte_count;
        !           459:        int             offset;
        !           460:                
        !           461:        read_str = read_flag ? "read " : "write";
        !           462:        offset = block * finfop->sectsize_info.sect_size;
        !           463:        byte_count = block_count * finfop->sectsize_info.sect_size;
        !           464:        rtn = lseek(fd, offset, L_SET);
        !           465:        if(rtn != offset) {
        !           466:                printf("Live Partition Seek Seek error on %s\n", read_str);
        !           467:                return(1);
        !           468:        }
        !           469:        if(read_flag) {
        !           470:                rtn = read(fd, addrs, byte_count);
        !           471:        }
        !           472:        else {
        !           473:                rtn = write(fd, addrs, byte_count);
        !           474:        }
        !           475:        if(rtn != byte_count) {
        !           476:                printf("\n");
        !           477:                if(rtn <= 0) {
        !           478:                        perror(read_str);
        !           479:                }
        !           480:                else {
        !           481:                        printf("Short %s (exp %d, recd %d)\n",
        !           482:                                read_str, byte_count, rtn);
        !           483:                }
        !           484:                printf("block %d block_count %d\n", block, block_count);
        !           485:                return(1);
        !           486:        }
        !           487:        return(0);
        !           488: } /* fd_rw() */
        !           489: 
        !           490: 
        !           491: #else  USE_LIVE_IO
        !           492: 
        !           493: int fd_rw(int fd,
        !           494:        int block,
        !           495:        int block_count,
        !           496:        u_char *addrs,
        !           497:        boolean_t read_flag,
        !           498:        struct fd_format_info *finfop)
        !           499: {
        !           500:        int rtn;
        !           501:        char *read_str;
        !           502:        int byte_count;
        !           503:        struct fd_rawio rawio;
        !           504:        
        !           505:        read_str = read_flag ? "read " : "write";
        !           506:                
        !           507:        rawio.sector = block;
        !           508:        rawio.sector_count = block_count;
        !           509:        rawio.dma_addrs = (caddr_t)addrs;
        !           510:        rawio.read = read_flag;
        !           511:        rawio.sects_xfr = rawio.status = -1;
        !           512:        
        !           513:        rtn = ioctl(fd, FDIOCRRW, &rawio);
        !           514:        if(rtn) {
        !           515:                if(read_flag)
        !           516:                        perror("ioctl(FDIOCRW, read)");
        !           517:                else
        !           518:                        perror("ioctl(FDIOCRW, write)");
        !           519:                return(1);
        !           520:                        
        !           521:        }
        !           522:        if(rawio.status != FDR_SUCCESS) {
        !           523:                printf("\n...%s: rawio.status = %d(d)\n",
        !           524:                        read_str, rawio.status);
        !           525:                return(1);
        !           526:        }
        !           527:        if(rawio.sects_xfr != block_count) {
        !           528:                printf("\n...ioctl(FDIOCRW, %s) moved %d(d) blocks, "
        !           529:                        "expected %d(d) blocks\n", 
        !           530:                        read_str, rawio.sects_xfr, block_count);
        !           531:                return(1);
        !           532:        }
        !           533:        return(0);
        !           534: } /* fd_rw() */
        !           535: 
        !           536: #endif USE_LIVE_IO
        !           537: 
        !           538: 
        !           539: 
        !           540: 
        !           541: 

unix.superglobalmegacorp.com

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