📄 xd.c.txt
字号:
447 printk("xd_command: warning! sense command failed!\n");
448 }
449
450 #ifdef DEBUG_COMMAND
451 printk("xd_command: completed with csb = 0x%X\n",csb);
452 #endif /* DEBUG_COMMAND */
453
454 return (csb & CSB_ERROR);
455 }
456
457 static u_char xd_initdrives (void (*init_drive)(u_char drive))
458 {
459 u_char cmdblk[6],i,count = 0;
460
461 for (i = 0; i < XD_MAXDRIVES; i++) {
462 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
463 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2)) {
464 init_drive(count);
465 count++;
466 }
467 }
468 return (count);
469 }
470
471 static void xd_dtc_init_controller (u_char *address)
472 {
473 switch ((u_long) address) {
474 case 0xC8000: xd_iobase = 0x320; break;
475 case 0xCA000: xd_iobase = 0x324; break;
476 default: printk("xd_dtc_init_controller: unsupported BIOS address %p\n",address);
477 xd_iobase = 0x320; break;
478 }
479 xd_irq = 5; /* the IRQ _can_ be changed on this card, but requires a hardware mod */
480 xd_dma = 3;
481 xd_maxsectors = 0x01; /* my card seems to have trouble doing multi-block transfers? */
482
483 outb(0,XD_RESET); /* reset the controller */
484 }
485
486 static void xd_dtc_init_drive (u_char drive)
487 {
488 u_char cmdblk[6],buf[64];
489
490 xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
491 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
492 xd_info[drive].heads = buf[0x0A]; /* heads */
493 xd_info[drive].cylinders = ((u_short *) (buf))[0x04]; /* cylinders */
494 xd_info[drive].sectors = 17; /* sectors */
495 #if 0
496 xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05]; /* reduced write */
497 xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06]; /* write precomp */
498 xd_info[drive].ecc = buf[0x0F]; /* ecc length */
499 #endif /* 0 */
500 xd_info[drive].control = 0; /* control byte */
501
502 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,((u_short *) (buf + 1))[0x05],((u_short *) (buf + 1))[0x06],buf[0x0F]);
503 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
504 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
505 printk("xd_dtc_init_drive: error setting step rate for drive %d\n",drive);
506 }
507 else
508 printk("xd_dtc_init_drive: error reading geometry for drive %d\n",drive);
509 }
510
511 static void xd_wd_init_controller (u_char *address)
512 {
513 switch ((u_long) address) {
514 case 0xC8000: xd_iobase = 0x320; break;
515 case 0xCA000: xd_iobase = 0x324; break;
516 case 0xCC000: xd_iobase = 0x328; break;
517 case 0xCE000: xd_iobase = 0x32C; break;
518 case 0xD0000: xd_iobase = 0x328; break;
519 case 0xD8000: xd_iobase = 0x32C; break;
520 default: printk("xd_wd_init_controller: unsupported BIOS address %p\n",address);
521 xd_iobase = 0x320; break;
522 }
523 xd_irq = 5; /* don't know how to auto-detect this yet */
524 xd_dma = 3;
525 xd_maxsectors = 0x01; /* this one doesn't wrap properly either... */
526
527 /* outb(0,XD_RESET); */ /* reset the controller */
528 }
529
530 static void xd_wd_init_drive (u_char drive)
531 {
532 u_char cmdblk[6],buf[0x200];
533
534 xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
535 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
536 xd_info[drive].heads = buf[0x1AF]; /* heads */
537 xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6]; /* cylinders */
538 xd_info[drive].sectors = 17; /* sectors */
539 #if 0
540 xd_info[drive].rwrite = ((u_short *) (buf))[0xD8]; /* reduced write */
541 xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA]; /* write precomp */
542 xd_info[drive].ecc = buf[0x1B4]; /* ecc length */
543 #endif /* 0 */
544 xd_info[drive].control = buf[0x1B5]; /* control byte */
545
546 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
547 }
548 else
549 printk("xd_wd_init_drive: error reading geometry for drive %d\n",drive);
550 }
551
552 static void xd_seagate_init_controller (u_char *address)
553 {
554 switch ((u_long) address) {
555 case 0xC8000: xd_iobase = 0x320; break;
556 case 0xD0000: xd_iobase = 0x324; break;
557 case 0xD8000: xd_iobase = 0x328; break;
558 case 0xE0000: xd_iobase = 0x32C; break;
559 default: printk("xd_seagate_init_controller: unsupported BIOS address %p\n",address);
560 xd_iobase = 0x320; break;
561 }
562 xd_irq = 5; /* the IRQ and DMA channel are fixed on the Seagate controllers */
563 xd_dma = 3;
564 xd_maxsectors = 0x40;
565
566 outb(0,XD_RESET); /* reset the controller */
567 }
568
569 static void xd_seagate_init_drive (u_char drive)
570 {
571 u_char cmdblk[6],buf[0x200];
572
573 xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
574 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
575 xd_info[drive].heads = buf[0x04]; /* heads */
576 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03]; /* cylinders */
577 xd_info[drive].sectors = buf[0x05]; /* sectors */
578 xd_info[drive].control = 0; /* control byte */
579 }
580 else
581 printk("xd_seagate_init_drive: error reading geometry from drive %d\n",drive);
582 }
583
584 /* Omti support courtesy Dirk Melchers */
585 static void xd_omti_init_controller (u_char *address)
586 {
587 switch ((u_long) address) {
588 case 0xC8000: xd_iobase = 0x320; break;
589 case 0xD0000: xd_iobase = 0x324; break;
590 case 0xD8000: xd_iobase = 0x328; break;
591 case 0xE0000: xd_iobase = 0x32C; break;
592 default: printk("xd_omti_init_controller: unsupported BIOS address %p\n",address);
593 xd_iobase = 0x320; break;
594 }
595
596 xd_irq = 5; /* the IRQ and DMA channel are fixed on the Omti controllers */
597 xd_dma = 3;
598 xd_maxsectors = 0x40;
599
600 outb(0,XD_RESET); /* reset the controller */
601 }
602
603 static void xd_omti_init_drive (u_char drive)
604 {
605 /* gets infos from drive */
606 xd_override_init_drive(drive);
607
608 /* set other parameters, Hardcoded, not that nice :-) */
609 xd_info[drive].control = 2;
610 }
611
612 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
613 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
614 static void xd_override_init_drive (u_char drive)
615 {
616 u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
617 u_char cmdblk[6],i;
618
619 for (i = 0; i < 3; i++) {
620 while (min[i] != max[i] - 1) {
621 test[i] = (min[i] + max[i]) / 2;
622 xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
623 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
624 min[i] = test[i];
625 else
626 max[i] = test[i];
627 }
628 test[i] = min[i];
629 }
630 xd_info[drive].heads = (u_char) min[0] + 1;
631 xd_info[drive].cylinders = (u_short) min[1] + 1;
632 xd_info[drive].sectors = (u_char) min[2] + 1;
633 xd_info[drive].control = 0;
634 }
635
636 /* xd_setup: initialise from command line parameters */
637 void xd_setup (char *command,int *integers)
638 {
639 xd_override = 1;
640
641 xd_type = integers[1];
642 xd_irq = integers[2];
643 xd_iobase = integers[3];
644 xd_dma = integers[4];
645
646 xd_maxsectors = 0x01;
647 }
648
649 /* xd_setparam: set the drive characteristics */
650 static void xd_setparam (u_char command,u_char drive,u_char heads,u_short cylinders,u_short rwrite,u_short wprecomp,u_char ecc)
651 {
652 u_char cmdblk[14];
653
654 xd_build(cmdblk,command,drive,0,0,0,0,0);
655 cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
656 cmdblk[7] = (u_char) (cylinders & 0xFF);
657 cmdblk[8] = heads & 0x1F;
658 cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
659 cmdblk[10] = (u_char) (rwrite & 0xFF);
660 cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
661 cmdblk[12] = (u_char) (wprecomp & 0xFF);
662 cmdblk[13] = ecc;
663
664 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
665 printk("xd_setparam: error setting characteristics for drive %d\n",drive);
666 }
667
668
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -