fdc.c (16629bd98267290324ab100941b280835c643d79) | fdc.c (a6e4d8c45383824144e371bb6adc8e877611c4c9) |
---|---|
1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Don Ahn. 7 * 8 * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu) --- 227 unchanged lines hidden (view full) --- 236#if 0 237static u_int8_t fdin_rd(fdc_p); 238#endif 239static int fdc_err(struct fdc_data *, const char *); 240static int enable_fifo(fdc_p fdc); 241static int fd_sense_drive_status(fdc_p, int *); 242static int fd_sense_int(fdc_p, int *, int *); 243static int fd_read_status(fdc_p); | 1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Don Ahn. 7 * 8 * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu) --- 227 unchanged lines hidden (view full) --- 236#if 0 237static u_int8_t fdin_rd(fdc_p); 238#endif 239static int fdc_err(struct fdc_data *, const char *); 240static int enable_fifo(fdc_p fdc); 241static int fd_sense_drive_status(fdc_p, int *); 242static int fd_sense_int(fdc_p, int *, int *); 243static int fd_read_status(fdc_p); |
244static void fdc_add_child(device_t, const char *, int); | |
245static int fd_probe(device_t); 246static int fd_attach(device_t); 247static int fd_detach(device_t); 248static void set_motor(struct fdc_data *, int, int); 249# define TURNON 1 250# define TURNOFF 0 251static timeout_t fd_turnoff; 252static timeout_t fd_motor_on; --- 259 unchanged lines hidden (view full) --- 512} 513 514void 515fdc_release_resources(struct fdc_data *fdc) 516{ 517 device_t dev; 518 519 dev = fdc->fdc_dev; | 244static int fd_probe(device_t); 245static int fd_attach(device_t); 246static int fd_detach(device_t); 247static void set_motor(struct fdc_data *, int, int); 248# define TURNON 1 249# define TURNOFF 0 250static timeout_t fd_turnoff; 251static timeout_t fd_motor_on; --- 259 unchanged lines hidden (view full) --- 511} 512 513void 514fdc_release_resources(struct fdc_data *fdc) 515{ 516 device_t dev; 517 518 dev = fdc->fdc_dev; |
519 if (fdc->fdc_intr) { 520 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 521 fdc->fdc_intr); 522 fdc->fdc_intr = NULL; 523 } |
|
520 if (fdc->res_irq != 0) { 521 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 522 fdc->res_irq); 523 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 524 fdc->res_irq); | 524 if (fdc->res_irq != 0) { 525 bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 526 fdc->res_irq); 527 bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq, 528 fdc->res_irq); |
529 fdc->res_irq = NULL; |
|
525 } 526 if (fdc->res_ctl != 0) { 527 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl, 528 fdc->res_ctl); 529 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl, 530 fdc->res_ctl); | 530 } 531 if (fdc->res_ctl != 0) { 532 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl, 533 fdc->res_ctl); 534 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ctl, 535 fdc->res_ctl); |
536 fdc->res_ctl = NULL; |
|
531 } 532 if (fdc->res_ioport != 0) { 533 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 534 fdc->res_ioport); 535 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 536 fdc->res_ioport); | 537 } 538 if (fdc->res_ioport != 0) { 539 bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 540 fdc->res_ioport); 541 bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport, 542 fdc->res_ioport); |
543 fdc->res_ioport = NULL; |
|
537 } 538 if (fdc->res_drq != 0) { 539 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 540 fdc->res_drq); 541 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 542 fdc->res_drq); | 544 } 545 if (fdc->res_drq != 0) { 546 bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 547 fdc->res_drq); 548 bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq, 549 fdc->res_drq); |
550 fdc->res_ioport = NULL; |
|
543 } 544} 545 546/* 547 * Configuration/initialization stuff, per controller. 548 */ 549 550int --- 57 unchanged lines hidden (view full) --- 608 609 /* have our children detached first */ 610 if ((error = bus_generic_detach(dev))) 611 return (error); 612 613 /* reset controller, turn motor off */ 614 fdout_wr(fdc, 0); 615 | 551 } 552} 553 554/* 555 * Configuration/initialization stuff, per controller. 556 */ 557 558int --- 57 unchanged lines hidden (view full) --- 616 617 /* have our children detached first */ 618 if ((error = bus_generic_detach(dev))) 619 return (error); 620 621 /* reset controller, turn motor off */ 622 fdout_wr(fdc, 0); 623 |
616 if ((fdc->flags & FDC_ATTACHED) == 0) { 617 device_printf(dev, "already unloaded\n"); 618 return (0); 619 } 620 fdc->flags &= ~FDC_ATTACHED; 621 622 BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq, 623 fdc->fdc_intr); | |
624 fdc_release_resources(fdc); 625 return (0); 626} 627 628/* 629 * Add a child device to the fdc controller. It will then be probed etc. 630 */ | 624 fdc_release_resources(fdc); 625 return (0); 626} 627 628/* 629 * Add a child device to the fdc controller. It will then be probed etc. 630 */ |
631static void | 631device_t |
632fdc_add_child(device_t dev, const char *name, int unit) 633{ | 632fdc_add_child(device_t dev, const char *name, int unit) 633{ |
634 int fdu, flags; | 634 int flags; |
635 struct fdc_ivars *ivar; 636 device_t child; 637 638 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO); 639 if (ivar == NULL) | 635 struct fdc_ivars *ivar; 636 device_t child; 637 638 ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT | M_ZERO); 639 if (ivar == NULL) |
640 return; | 640 return (NULL); |
641 child = device_add_child(dev, name, unit); 642 if (child == NULL) { 643 free(ivar, M_DEVBUF); | 641 child = device_add_child(dev, name, unit); 642 if (child == NULL) { 643 free(ivar, M_DEVBUF); |
644 return; | 644 return (NULL); |
645 } 646 device_set_ivars(child, ivar); | 645 } 646 device_set_ivars(child, ivar); |
647 if (resource_int_value(name, unit, "drive", &fdu) != 0) 648 fdu = 0; 649 fdc_set_fdunit(child, fdu); 650 fdc_set_fdtype(child, FDT_NONE); | 647 ivar->fdunit = unit; 648 ivar->fdtype = FDT_NONE; |
651 if (resource_int_value(name, unit, "flags", &flags) == 0) 652 device_set_flags(child, flags); 653 if (resource_disabled(name, unit)) 654 device_disable(child); | 649 if (resource_int_value(name, unit, "flags", &flags) == 0) 650 device_set_flags(child, flags); 651 if (resource_disabled(name, unit)) 652 device_disable(child); |
653 return (child); |
|
655} 656 657int 658fdc_attach(device_t dev) 659{ 660 struct fdc_data *fdc; | 654} 655 656int 657fdc_attach(device_t dev) 658{ 659 struct fdc_data *fdc; |
661 const char *name, *dname; 662 int i, dunit, error; | 660 int error; |
663 664 fdc = device_get_softc(dev); 665 fdc->fdc_dev = dev; 666 error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq, 667 INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc, 668 &fdc->fdc_intr); 669 if (error) { 670 device_printf(dev, "cannot setup interrupt\n"); 671 return error; 672 } 673 fdc->fdcu = device_get_unit(dev); | 661 662 fdc = device_get_softc(dev); 663 fdc->fdc_dev = dev; 664 error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq, 665 INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc, 666 &fdc->fdc_intr); 667 if (error) { 668 device_printf(dev, "cannot setup interrupt\n"); 669 return error; 670 } 671 fdc->fdcu = device_get_unit(dev); |
674 fdc->flags |= FDC_ATTACHED | FDC_NEEDS_RESET; | 672 fdc->flags |= FDC_NEEDS_RESET; |
675 676 fdc->state = DEVIDLE; 677 678 /* reset controller, turn motor off, clear fdout mirror reg */ 679 fdout_wr(fdc, fdc->fdout = 0); 680 bioq_init(&fdc->head); 681 | 673 674 fdc->state = DEVIDLE; 675 676 /* reset controller, turn motor off, clear fdout mirror reg */ 677 fdout_wr(fdc, fdc->fdout = 0); 678 bioq_init(&fdc->head); 679 |
680 return (0); 681} 682 683int 684fdc_hints_probe(device_t dev) 685{ 686 const char *name, *dname; 687 int i, error, dunit; 688 |
|
682 /* 683 * Probe and attach any children. We should probably detect 684 * devices from the BIOS unless overridden. 685 */ 686 name = device_get_nameunit(dev); 687 i = 0; | 689 /* 690 * Probe and attach any children. We should probably detect 691 * devices from the BIOS unless overridden. 692 */ 693 name = device_get_nameunit(dev); 694 i = 0; |
688 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) | 695 while ((resource_find_match(&i, &dname, &dunit, "at", name)) == 0) { 696 resource_int_value(dname, dunit, "drive", &dunit); |
689 fdc_add_child(dev, dname, dunit); | 697 fdc_add_child(dev, dname, dunit); |
698 } |
|
690 691 if ((error = bus_generic_attach(dev)) != 0) 692 return (error); | 699 700 if ((error = bus_generic_attach(dev)) != 0) 701 return (error); |
693 | |
694 return (0); 695} 696 697int 698fdc_print_child(device_t me, device_t child) 699{ 700 int retval = 0, flags; 701 --- 25 unchanged lines hidden (view full) --- 727 fdc = device_get_softc(device_get_parent(dev)); 728 flags = device_get_flags(dev); 729 730 fd->dev = dev; 731 fd->fdc = fdc; 732 fd->fdsu = fdsu; 733 fd->fdu = device_get_unit(dev); 734 | 702 return (0); 703} 704 705int 706fdc_print_child(device_t me, device_t child) 707{ 708 int retval = 0, flags; 709 --- 25 unchanged lines hidden (view full) --- 735 fdc = device_get_softc(device_get_parent(dev)); 736 flags = device_get_flags(dev); 737 738 fd->dev = dev; 739 fd->fdc = fdc; 740 fd->fdsu = fdsu; 741 fd->fdu = device_get_unit(dev); 742 |
735 type = FD_DTYPE(flags); 736 | |
737 /* Auto-probe if fdinfo is present, but always allow override. */ | 743 /* Auto-probe if fdinfo is present, but always allow override. */ |
744 type = FD_DTYPE(flags); |
|
738 if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) { 739 fd->type = type; 740 goto done; 741 } else { 742 /* make sure fdautoselect() will be called */ 743 fd->flags = FD_UA; 744 fd->type = type; 745 } --- 69 unchanged lines hidden (view full) --- 815 816 set_motor(fdc, fdsu, TURNOFF); 817 818 if ((flags & FD_NO_PROBE) == 0 && 819 (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */ 820 return (ENXIO); 821 822done: | 745 if (type == FDT_NONE && (type = fdc_get_fdtype(dev)) != FDT_NONE) { 746 fd->type = type; 747 goto done; 748 } else { 749 /* make sure fdautoselect() will be called */ 750 fd->flags = FD_UA; 751 fd->type = type; 752 } --- 69 unchanged lines hidden (view full) --- 822 823 set_motor(fdc, fdsu, TURNOFF); 824 825 if ((flags & FD_NO_PROBE) == 0 && 826 (st0 & NE7_ST0_EC) != 0) /* no track 0 -> no drive present */ 827 return (ENXIO); 828 829done: |
823 /* This doesn't work before the first reset. Or set_motor?? */ | 830 /* This doesn't work before the first reset. */ |
824 if ((fdc->flags & FDC_HAS_FIFO) == 0 && 825 fdc->fdct == FDC_ENHANCED && 826 (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 && 827 enable_fifo(fdc) == 0) { 828 device_printf(device_get_parent(dev), 829 "FIFO enabled, %d bytes threshold\n", fifo_threshold); 830 } 831 --- 1492 unchanged lines hidden --- | 831 if ((fdc->flags & FDC_HAS_FIFO) == 0 && 832 fdc->fdct == FDC_ENHANCED && 833 (device_get_flags(fdc->fdc_dev) & FDC_NO_FIFO) == 0 && 834 enable_fifo(fdc) == 0) { 835 device_printf(device_get_parent(dev), 836 "FIFO enabled, %d bytes threshold\n", fifo_threshold); 837 } 838 --- 1492 unchanged lines hidden --- |