Lines Matching refs:fdc

41  *	if we ever have > 1 fdc, we'll have to see what that means. This
111 #define KIOIP KSTAT_INTR_PTR(fdc->c_intrstat)
182 static int fd_attach_check_drive(struct fdctlr *fdc);
183 static int fd_attach_det_ctlr(dev_info_t *dip, struct fdctlr *fdc);
184 static int fd_attach_map_regs(dev_info_t *dip, struct fdctlr *fdc);
185 static int fd_attach_register_interrupts(dev_info_t *dip, struct fdctlr *fdc,
189 static int fdcheckdisk(struct fdctlr *fdc, int unit);
191 static void fd_cleanup(dev_info_t *dip, struct fdctlr *fdc, int hard,
194 static int fdexec(struct fdctlr *fdc, int flags);
195 static void fdexec_turn_on_motor(struct fdctlr *fdc, int flags, uint_t unit);
196 static int fdformat(struct fdctlr *fdc, int unit, int cyl, int hd);
200 static int fdgetlabel(struct fdctlr *fdc, int unit);
209 static int fdrecalseek(struct fdctlr *fdc, int unit, int arg, int execflg);
213 static int fdrw(struct fdctlr *fdc, int, int, int, int, int, caddr_t, uint_t);
214 static void fdselect(struct fdctlr *fdc, int unit, int onoff);
215 static int fdsensedrv(struct fdctlr *fdc, int unit);
218 static int fdstart_dma(register struct fdctlr *fdc, caddr_t addr, uint_t len);
225 static int fd_pm_lower_power(struct fdctlr *fdc);
226 static int fd_pm_raise_power(struct fdctlr *fdc);
228 static void set_data_count_register(struct fdctlr *fdc, uint32_t count);
229 static uint32_t get_data_count_register(struct fdctlr *fdc);
230 static void reset_dma_controller(struct fdctlr *fdc);
231 static void set_data_address_register(struct fdctlr *fdc, uint32_t address);
232 static uint32_t get_dma_control_register(struct fdctlr *fdc);
233 static void set_dma_mode(struct fdctlr *fdc, int val);
234 static void set_dma_control_register(struct fdctlr *fdc, uint32_t val);
235 static void release_sb_dma(struct fdctlr *fdc);
258 #define CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc) \
260 while (fdc->c_un->un_state == FD_STATE_SUSPENDED) {\
261 cv_wait(&fdc->c_suspend_cv, \
262 &fdc->c_lolock);\
597 struct fdctlr *fdc;
609 if (!(fdc = fd_getctlr(instance << FDINSTSHIFT))) {
612 quiesce_fd_interrupt(fdc);
613 if (fdc->c_fdtype & FDCTYPE_SB)
614 if (ddi_add_intr(dip, 0, &fdc->c_block, 0,
620 mutex_enter(&fdc->c_lolock);
625 cv_broadcast(&fdc->c_suspend_cv);
626 mutex_exit(&fdc->c_lolock);
645 fdc = kmem_zalloc(sizeof (*fdc), KM_SLEEP);
646 fdc->c_dip = dip;
649 fdc->c_next = fdctlrs;
650 fdctlrs = fdc;
653 if (fd_attach_det_ctlr(dip, fdc) == DDI_FAILURE) {
654 fd_cleanup(dip, fdc, hard_intr_set, 0);
658 if (fd_attach_map_regs(dip, fdc) == DDI_FAILURE) {
659 fd_cleanup(dip, fdc, hard_intr_set, 0);
666 if (fdc->c_fdtype & FDCTYPE_DMA) {
667 fdc->c_fd_dma_lim.dma_attr_version = DMA_ATTR_V0;
668 fdc->c_fd_dma_lim.dma_attr_addr_lo = 0x00000000ull;
669 fdc->c_fd_dma_lim.dma_attr_addr_hi = 0xfffffffeull;
670 fdc->c_fd_dma_lim.dma_attr_count_max = 0xffffff;
671 if (fdc->c_fdtype & FDCTYPE_SB) {
672 fdc->c_fd_dma_lim.dma_attr_align = FD_SB_DMA_ALIGN;
674 fdc->c_fd_dma_lim.dma_attr_align = 1;
676 fdc->c_fd_dma_lim.dma_attr_burstsizes = 0x0;
677 fdc->c_fd_dma_lim.dma_attr_minxfer = 1;
678 fdc->c_fd_dma_lim.dma_attr_maxxfer = 0xffff;
679 fdc->c_fd_dma_lim.dma_attr_seg = 0xffff;
680 fdc->c_fd_dma_lim.dma_attr_sgllen = 1;
681 fdc->c_fd_dma_lim.dma_attr_granular = 512;
683 if (ddi_dma_alloc_handle(dip, &fdc->c_fd_dma_lim,
684 DDI_DMA_DONTWAIT, 0, &fdc->c_dmahandle) != DDI_SUCCESS) {
685 fd_cleanup(dip, fdc, hard_intr_set, 0);
689 if (fdc->c_fdtype & FDCTYPE_SB) {
697 if (ddi_dma_mem_alloc(fdc->c_dmahandle,
699 DDI_DMA_SLEEP, NULL, (caddr_t *)&fdc->dma_buf,
700 &rlen, &fdc->c_dma_buf_handle) != DDI_SUCCESS) {
701 fd_cleanup(dip, fdc, hard_intr_set, 0);
710 if (fd_attach_register_interrupts(dip, fdc,
712 fd_cleanup(dip, fdc, hard_intr_set, 0);
726 fdc->c_un = kmem_zalloc(sizeof (struct fdunit), KM_SLEEP);
727 fdc->c_un->un_chars = kmem_alloc(sizeof (struct fd_char), KM_SLEEP);
728 fdc->c_un->un_iostat = kstat_create("fd", 0, "fd0", "disk",
730 if (fdc->c_un->un_iostat) {
731 fdc->c_un->un_iostat->ks_lock = &fdc->c_lolock;
732 kstat_install(fdc->c_un->un_iostat);
735 fdc->c_un->un_drive = kmem_zalloc(sizeof (struct fd_drive), KM_SLEEP);
740 fdc->c_un->un_drive->fdd_ejectable = 0;
743 fdc->c_un->un_drive->fdd_ejectable = -1;
747 fdc->c_un->un_drive->fdd_ejectable));
753 fdc->c_un->un_unit_no = ddi_getprop(DDI_DEV_T_ANY, dip,
757 if (fdc->c_fdtype & FDCTYPE_SB) {
758 fdc->sb_dma_channel = ddi_getprop(DDI_DEV_T_ANY, dip,
764 fdc->c_un->un_unit_no));
767 fdc->c_un->un_curfdtype = 1;
768 *fdc->c_un->un_chars = fdtypes[fdc->c_un->un_curfdtype];
769 fdunpacklabel(&fdlbl_high_80, &fdc->c_un->un_label);
772 if (fd_attach_check_drive(fdc) == DDI_FAILURE) {
773 fd_cleanup(dip, fdc, hard_intr_set, 1);
781 fd_cleanup(dip, fdc, hard_intr_set, 1);
807 fd_attach_map_regs(dev_info_t *dip, struct fdctlr *fdc)
816 if (fdc->c_fdtype & FDCTYPE_SB) {
817 if (ddi_regs_map_setup(dip, 1, (caddr_t *)&fdc->c_dma_regs,
819 &fdc->c_handlep_dma)) {
824 } else if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
825 if (ddi_regs_map_setup(dip, 1, (caddr_t *)&fdc->c_dma_regs,
827 &fdc->c_handlep_dma)) {
833 reset_dma_controller(fdc);
834 set_dma_control_register(fdc, DCSR_INIT_BITS);
837 switch (fdc->c_fdtype & FDCTYPE_CTRLMASK) {
843 fdc->c_control =
844 (uchar_t *)&fdc->c_reg->fdc_82077_reg.fdc_control;
845 fdc->c_fifo = (uchar_t *)&fdc->c_reg->fdc_82077_reg.fdc_fifo;
846 fdc->c_dor = (uchar_t *)&fdc->c_reg->fdc_82077_reg.fdc_dor;
847 fdc->c_dir = (uchar_t *)&fdc->c_reg->fdc_82077_reg.fdc_dir;
852 (void *)fdc->c_control));
860 quiesce_fd_interrupt(fdc);
874 fd_attach_det_ctlr(dev_info_t *dip, struct fdctlr *fdc)
891 if (ddi_regs_map_setup(dip, 0, (caddr_t *)&fdc->c_reg,
894 &fdc->c_handlep_cont)) {
909 fdc->c_fdtype |= FDCTYPE_SLAVIO;
910 fdc->c_fdtype |= FDCTYPE_82077;
911 fdc->c_auxiova = fd_getauxiova(dip);
912 fdc->c_auxiodata = (uchar_t)(AUX_MBO4M|AUX_TC4M);
913 fdc->c_auxiodata2 = (uchar_t)AUX_TC4M;
924 fdc->c_fdtype |= FDCTYPE_SB;
925 fdc->c_fdtype |= FDCTYPE_82077;
926 fdc->c_fdtype |= FDCTYPE_DMA;
936 fdc->c_fdtype |= FDCTYPE_DMA8237;
942 fdc->c_fdtype |= FDCTYPE_CHEERIO;
943 fdc->c_fdtype |= FDCTYPE_82077;
952 if (ddi_regs_map_setup(dip, 2, (caddr_t *)&fdc->c_auxio_reg,
953 0, sizeof (uint_t), &attr, &fdc->c_handlep_aux)) {
961 Set_auxio(fdc, AUX_HIGH_DENSITY);
964 *fdc->c_auxio_reg));
966 fdc->c_fdtype |= FDCTYPE_DMA;
971 if (fdc->c_fdtype == 0) {
985 fd_attach_register_interrupts(dev_info_t *dip, struct fdctlr *fdc, int *hard)
997 if (ddi_get_iblock_cookie(dip, 0, &fdc->c_block) != DDI_SUCCESS) {
1005 mutex_init(&fdc->c_hilock, NULL, MUTEX_DRIVER, fdc->c_block);
1012 if (fdc->c_fdtype & FDCTYPE_DMA) {
1013 if (ddi_add_intr(dip, 0, &fdc->c_block, 0,
1022 mutex_init(&fdc->c_lolock, NULL,
1023 MUTEX_DRIVER, fdc->c_block);
1030 mutex_destroy(&fdc->c_hilock);
1039 if (ddi_add_intr(dip, 0, &fdc->c_block, 0,
1046 fdc->c_fasttrap = 0;
1052 mutex_destroy(&fdc->c_hilock);
1068 mutex_destroy(&fdc->c_hilock);
1076 mutex_init(&fdc->c_lolock, NULL, MUTEX_DRIVER,
1079 if (ddi_add_softintr(dip, DDI_SOFTINT_LOW, &fdc->c_softid,
1082 (caddr_t)fdc) != DDI_SUCCESS) {
1084 mutex_destroy(&fdc->c_hilock);
1085 mutex_destroy(&fdc->c_lolock);
1091 fdc->c_intrstat = kstat_create("fd", 0, "fdc0", "controller",
1093 if (fdc->c_intrstat) {
1094 fdc->c_hiintct = &KIOIP->intrs[KSTAT_INTR_HARD];
1095 kstat_install(fdc->c_intrstat);
1099 cv_init(&fdc->c_iocv, NULL, CV_DRIVER, NULL);
1102 cv_init(&fdc->c_csbcv, NULL, CV_DRIVER, NULL);
1105 cv_init(&fdc->c_motoncv, NULL, CV_DRIVER, NULL);
1108 sema_init(&fdc->c_ocsem, 1, NULL, SEMA_DRIVER, NULL);
1111 cv_init(&fdc->c_suspend_cv, NULL, CV_DRIVER, NULL);
1121 fd_attach_check_drive(struct fdctlr *fdc)
1124 int unit = fdc->c_un->un_unit_no;
1130 mutex_enter(&fdc->c_lolock);
1131 switch (fdc->c_fdtype & FDCTYPE_CTRLMASK) {
1142 Set_dor(fdc, ~((MOTEN(unit))|DRVSEL|RESET), 0);
1145 (C, "fdattach: Dor 0x%x\n", Dor(fdc)));
1150 Set_dor(fdc, RESET|DRVSEL, 1);
1154 Set_dor(fdc, DRVSEL, 0);
1156 Set_dor(fdc, RESET, 1);
1162 (C, "fdattach: Dor 0x%x\n", Dor(fdc)));
1164 if (!((fdc->c_fdtype & FDCTYPE_CHEERIO) ||
1165 (fdc->c_fdtype & FDCTYPE_SB))) {
1174 fdgetcsb(fdc);
1175 if (fdreset(fdc) != 0) {
1176 mutex_exit(&fdc->c_lolock);
1192 if (fdrecalseek(fdc, unit, -1, 0) != 0) {
1193 timeout_id_t timeid = fdc->c_mtimeid;
1195 fdc->c_mtimeid = 0;
1196 mutex_exit(&fdc->c_lolock);
1212 fdselect(fdc, unit, 0); /* deselect drive zero (used in fdreset) */
1213 fdretcsb(fdc);
1214 mutex_exit(&fdc->c_lolock);
1234 fd_cleanup(dev_info_t *dip, struct fdctlr *fdc, int hard, int locks)
1240 ddi_get_instance(dip), (void *)fdc));
1243 if (fdc == NULL) {
1254 ddi_remove_intr(dip, (uint_t)0, fdc->c_block);
1258 if (fdc->c_softid != NULL)
1259 ddi_remove_softintr(fdc->c_softid);
1263 if (fdc->c_fdtype & FDCTYPE_82077) {
1264 if (fdc->c_mtimeid)
1265 (void) untimeout(fdc->c_mtimeid);
1270 fdmotoff(fdc);
1272 if (fdc->c_timeid)
1273 (void) untimeout(fdc->c_timeid);
1277 if (fdc->c_handlep_cont)
1278 ddi_regs_map_free(&fdc->c_handlep_cont);
1280 if (fdc->c_handlep_aux)
1281 ddi_regs_map_free(&fdc->c_handlep_aux);
1283 if (fdc->c_handlep_dma)
1284 ddi_regs_map_free(&fdc->c_handlep_dma);
1286 if (fdc->c_dma_buf_handle != NULL)
1287 ddi_dma_mem_free(&fdc->c_dma_buf_handle);
1289 if (fdc->c_dmahandle != NULL)
1290 ddi_dma_free_handle(&fdc->c_dmahandle);
1299 if (fdc->c_un != (struct fdunit *)NULL) {
1301 ASSERT(!mutex_owned(&fdc->c_lolock));
1303 if (fdc->c_un->un_iostat)
1304 kstat_delete(fdc->c_un->un_iostat);
1305 fdc->c_un->un_iostat = NULL;
1307 if (fdc->c_un->un_chars)
1308 kmem_free(fdc->c_un->un_chars, sizeof (struct fd_char));
1310 if (fdc->c_un->un_drive)
1311 kmem_free(fdc->c_un->un_drive,
1314 kmem_free((caddr_t)fdc->c_un, sizeof (struct fdunit));
1317 if (fdc->c_intrstat) {
1321 kstat_delete(fdc->c_intrstat);
1324 fdc->c_intrstat = NULL;
1327 cv_destroy(&fdc->c_iocv);
1328 cv_destroy(&fdc->c_csbcv);
1329 cv_destroy(&fdc->c_motoncv);
1330 cv_destroy(&fdc->c_suspend_cv);
1331 sema_destroy(&fdc->c_ocsem);
1332 mutex_destroy(&fdc->c_hilock);
1333 mutex_destroy(&fdc->c_lolock);
1337 fdctlrs = fdc->c_next;
1338 kmem_free(fdc, sizeof (*fdc));
1348 struct fdctlr *fdc = fd_getctlr(instance << FDINSTSHIFT);
1362 fd_cleanup(dip, fdc, 1, 1);
1369 if (!fdc)
1373 mutex_enter(&fdc->c_lolock);
1374 fdgetcsb(fdc); /* Wait for I/O to finish */
1375 c_mtimeid = fdc->c_mtimeid;
1376 fdretcsb(fdc);
1377 mutex_exit(&fdc->c_lolock);
1389 if (fdc->c_fdtype & FDCTYPE_SB)
1390 ddi_remove_intr(dip, 0, fdc->c_block);
1392 fdc->c_un->un_state = FD_STATE_SUSPENDED;
1405 register struct fdctlr *fdc;
1411 if ((fdc = fd_getctlr((dev_t)arg)) == NULL) {
1414 *result = fdc->c_dip;
1439 struct fdctlr *fdc;
1452 fdc = fd_getctlr(dev);
1453 if (fdc == NULL)
1457 un = fdc->c_un;
1458 if ((un == NULL) || !fd_unit_is_open(fdc->c_un))
1476 struct fdctlr *fdc;
1484 fdc = fd_getctlr(dev);
1485 if ((fdc == NULL) || ((un = fdc->c_un) == NULL)) {
1489 unit = fdc->c_un->un_unit_no;
1495 sema_p(&fdc->c_ocsem);
1502 sema_v(&fdc->c_ocsem);
1508 ddi_get_instance(fdc->c_dip), unit, part));
1517 (void) pm_busy_component(fdc->c_dip, 0);
1519 mutex_enter(&fdc->c_lolock);
1521 CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc);
1523 if (fdc->c_un->un_state == FD_STATE_STOPPED) {
1524 mutex_exit(&fdc->c_lolock);
1525 if ((pm_raise_power(fdc->c_dip, 0, PM_LEVEL_ON))
1530 sema_v(&fdc->c_ocsem);
1531 (void) pm_idle_component(fdc->c_dip, 0);
1534 mutex_enter(&fdc->c_lolock);
1537 fdgetcsb(fdc);
1541 err = fdrecalseek(fdc, unit, -1, 0);
1542 fdretcsb(fdc);
1547 fdselect(fdc, unit, 0);
1548 mutex_exit(&fdc->c_lolock);
1549 sema_v(&fdc->c_ocsem);
1550 (void) pm_idle_component(fdc->c_dip, 0);
1564 mutex_exit(&fdc->c_lolock);
1565 sema_v(&fdc->c_ocsem);
1567 (void) pm_idle_component(fdc->c_dip, 0);
1578 fdc->c_csb.csb_unit = (uchar_t)unit;
1579 if (fdgetlabel(fdc, unit)) {
1587 fdselect(fdc, unit, 0);
1590 mutex_exit(&fdc->c_lolock);
1591 sema_v(&fdc->c_ocsem);
1592 (void) pm_idle_component(fdc->c_dip, 0);
1600 fdgetcsb(fdc);
1601 err = fdsensedrv(fdc, unit) & WP_SR3;
1602 fdretcsb(fdc);
1605 fdselect(fdc, unit, 0);
1606 mutex_exit(&fdc->c_lolock);
1607 sema_v(&fdc->c_ocsem);
1608 (void) pm_idle_component(fdc->c_dip, 0);
1625 mutex_exit(&fdc->c_lolock);
1626 sema_v(&fdc->c_ocsem);
1627 (void) pm_idle_component(fdc->c_dip, 0);
1651 register struct fdctlr *fdc;
1654 fdc = fd_getctlr(dev);
1655 if (!fdc || !(un = fdc->c_un))
1659 unit = fdc->c_un->un_unit_no;
1663 sema_p(&fdc->c_ocsem);
1664 mutex_enter(&fdc->c_lolock);
1678 fdselect(fdc, unit, 0);
1681 mutex_exit(&fdc->c_lolock);
1682 sema_v(&fdc->c_ocsem);
1696 struct fdctlr *fdc;
1707 fdc = fd_getctlr(bp->b_edev);
1708 un = fdc->c_un;
1785 sema_p(&fdc->c_ocsem);
1787 (void) pm_busy_component(fdc->c_dip, 0);
1789 mutex_enter(&fdc->c_lolock);
1791 CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc);
1793 if (fdc->c_un->un_state == FD_STATE_STOPPED) {
1794 mutex_exit(&fdc->c_lolock);
1795 if ((pm_raise_power(fdc->c_dip, 0, PM_LEVEL_ON))
1797 sema_v(&fdc->c_ocsem);
1798 (void) pm_idle_component(fdc->c_dip, 0);
1805 mutex_enter(&fdc->c_lolock);
1811 if (fdc->c_actf)
1812 fdc->c_actl->av_forw = bp;
1814 fdc->c_actf = bp;
1815 fdc->c_actl = bp;
1819 fdstart(fdc);
1821 mutex_exit(&fdc->c_lolock);
1822 sema_v(&fdc->c_ocsem);
1823 (void) pm_idle_component(fdc->c_dip, 0);
1846 struct fdctlr *fdc = arg;
1847 int unit = fdc->c_un->un_unit_no;
1849 mutex_enter(&fdc->c_lolock);
1852 if (fdc->c_mtimeid == 0) {
1853 mutex_exit(&fdc->c_lolock);
1859 fdc->c_mtimeid = 0;
1861 if (!(Msr(fdc) & CB) && (Dor(fdc) & (MOTEN(unit)))) {
1863 Set_dor(fdc, MOTEN(unit), 0);
1866 mutex_exit(&fdc->c_lolock);
1885 struct fdctlr *fdc;
1899 fdc = fd_getctlr(dev);
1900 unit = fdc->c_un->un_unit_no;
1901 un = fdc->c_un;
1945 if (fdc->c_fdtype & FDCTYPE_82077)
2015 mutex_enter(&fdc->c_lolock);
2020 mutex_exit(&fdc->c_lolock);
2032 mutex_enter(&fdc->c_lolock);
2039 mutex_exit(&fdc->c_lolock);
2046 mutex_enter(&fdc->c_lolock);
2054 if (fdgetlabel(fdc, unit)) {
2055 mutex_exit(&fdc->c_lolock);
2062 mutex_exit(&fdc->c_lolock);
2115 mutex_enter(&fdc->c_lolock);
2124 mutex_exit(&fdc->c_lolock);
2130 mutex_exit(&fdc->c_lolock);
2134 (void) pm_busy_component(fdc->c_dip, 0);
2136 err = fdrw(fdc, unit, FDWRITE, 0, 0, 1,
2138 mutex_exit(&fdc->c_lolock);
2139 (void) pm_idle_component(fdc->c_dip, 0);
2148 (void) pm_busy_component(fdc->c_dip, 0);
2151 (void) pm_idle_component(fdc->c_dip, 0);
2208 mutex_enter(&fdc->c_lolock);
2213 mutex_exit(&fdc->c_lolock);
2222 if (fdc->c_un->un_drive->fdd_ejectable == 0) {
2227 (void) pm_busy_component(fdc->c_dip, 0);
2229 mutex_enter(&fdc->c_lolock);
2231 CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc);
2233 if (fdc->c_un->un_state == FD_STATE_STOPPED) {
2234 mutex_exit(&fdc->c_lolock);
2235 if ((pm_raise_power(fdc->c_dip, 0,
2237 (void) pm_idle_component(fdc->c_dip, 0);
2240 mutex_enter(&fdc->c_lolock);
2244 fdselect(fdc, unit, 1);
2245 fdeject(fdc, unit);
2246 mutex_exit(&fdc->c_lolock);
2249 (void) pm_idle_component(fdc->c_dip, 0);
2254 if (fdc->c_fdtype & FDCTYPE_82077) {
2255 if (fdc->c_mtimeid == 0) {
2256 fdc->c_mtimeid = timeout(fdmotoff, fdc,
2273 (void) pm_busy_component(fdc->c_dip, 0);
2275 mutex_enter(&fdc->c_lolock);
2277 CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc);
2279 if (fdc->c_un->un_state == FD_STATE_STOPPED) {
2280 mutex_exit(&fdc->c_lolock);
2281 if ((pm_raise_power(fdc->c_dip, 0, PM_LEVEL_ON))
2285 (void) pm_idle_component(fdc->c_dip, 0);
2289 mutex_enter(&fdc->c_lolock);
2303 if (fdsense_chng(fdc, unit)) {
2310 if (fdsense_chng(fdc, unit)) {
2316 if (fdcheckdisk(fdc, unit)) {
2356 fdgetcsb(fdc);
2357 if (fdsensedrv(fdc, unit) & WP_SR3) {
2360 fdretcsb(fdc);
2361 mutex_exit(&fdc->c_lolock);
2366 (void) pm_idle_component(fdc->c_dip, 0);
2381 cpy.drvchar.fdd_ejectable = fdc->c_un->un_drive->fdd_ejectable;
2504 (void) pm_busy_component(fdc->c_dip, 0);
2506 mutex_enter(&fdc->c_lolock);
2507 CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc);
2508 if (fdc->c_un->un_state == FD_STATE_STOPPED) {
2509 mutex_exit(&fdc->c_lolock);
2510 if ((pm_raise_power(fdc->c_dip, 0, PM_LEVEL_ON))
2514 (void) pm_idle_component(fdc->c_dip, 0);
2518 mutex_enter(&fdc->c_lolock);
2521 if (fdformat(fdc, unit, cyl, hd))
2524 mutex_exit(&fdc->c_lolock);
2525 (void) pm_idle_component(fdc->c_dip, 0);
2532 (void) pm_busy_component(fdc->c_dip, 0);
2533 err = fdrawioctl(fdc, unit, arg, flag);
2535 (void) pm_idle_component(fdc->c_dip, 0);
2563 fdrawioctl(struct fdctlr *fdc, int unit, intptr_t arg, int mode)
2582 ASSERT(fdc->c_un->un_unit_no == unit);
2621 mutex_enter(&fdc->c_lolock);
2623 CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc);
2625 if (fdc->c_un->un_state == FD_STATE_STOPPED) {
2626 mutex_exit(&fdc->c_lolock);
2627 if ((pm_raise_power(fdc->c_dip, 0, PM_LEVEL_ON))
2632 (void) pm_idle_component(fdc->c_dip, 0);
2635 mutex_enter(&fdc->c_lolock);
2638 fdgetcsb(fdc);
2639 csb = &fdc->c_csb;
2659 if (fdc->c_fdtype & FDCTYPE_DMA)
2697 if (fdc->c_fdtype & FDCTYPE_DMA) {
2700 mutex_enter(&fdc->c_hilock);
2702 res = ddi_dma_mem_alloc(fdc->c_dmahandle, fc,
2708 fdretcsb(fdc);
2709 mutex_exit(&fdc->c_lolock);
2710 mutex_exit(&fdc->c_hilock);
2714 fdc->c_csb.csb_read = CSB_WRITE;
2715 if (fdstart_dma(fdc, fa, fc) != 0) {
2717 fdretcsb(fdc);
2718 mutex_exit(&fdc->c_lolock);
2719 mutex_exit(&fdc->c_hilock);
2722 mutex_exit(&fdc->c_hilock);
2732 fdretcsb(fdc);
2733 mutex_exit(&fdc->c_lolock);
2735 if (fdc->c_fdtype & FDCTYPE_DMA) {
2758 if (fdc->c_fdtype & FDCTYPE_SB)
2765 fdretcsb(fdc);
2766 mutex_exit(&fdc->c_lolock);
2771 fdretcsb(fdc);
2772 mutex_exit(&fdc->c_lolock);
2789 if (fdc->c_fdtype & FDCTYPE_DMA) {
2790 mutex_enter(&fdc->c_hilock);
2791 res = ddi_dma_mem_alloc(fdc->c_dmahandle, fc,
2797 fdretcsb(fdc);
2798 mutex_exit(&fdc->c_lolock);
2799 mutex_exit(&fdc->c_hilock);
2804 fdc->c_csb.csb_read = CSB_WRITE;
2806 fdc->c_csb.csb_read = CSB_READ;
2808 if (fdstart_dma(fdc, fa, fc) != 0) {
2810 fdretcsb(fdc);
2811 mutex_exit(&fdc->c_lolock);
2812 mutex_exit(&fdc->c_hilock);
2815 mutex_exit(&fdc->c_hilock);
2823 if (fdc->c_fdtype & FDCTYPE_DMA)
2827 fdretcsb(fdc);
2828 mutex_exit(&fdc->c_lolock);
2866 (void) fdexec(fdc, 0); /* don't sleep, don't check change */
2868 (void) fdexec(fdc, FDXC_SLEEP | FDXC_CHECKCHG);
2890 if (fdc->c_fdtype & FDCTYPE_DMA) {
2903 fdr.fdr_nbytes = fdc->c_csb.csb_rlen; /* return resid */
2931 fdretcsb(fdc);
2932 mutex_exit(&fdc->c_lolock);
2940 * (sizeof fdc's fifo) of dummy on end. This is so than when fdc->c_len
2947 fdformat(struct fdctlr *fdc, int unit, int cyl, int hd)
2962 fdgetcsb(fdc);
2964 ASSERT(fdc->c_un->un_unit_no == unit);
2966 csb = &fdc->c_csb;
2967 un = fdc->c_un;
2977 if (fdrecalseek(fdc, unit, cyl, FDXC_CHECKCHG)) {
2978 fdretcsb(fdc);
3006 if (fdc->c_fdtype & FDCTYPE_DMA) {
3014 mutex_enter(&fdc->c_hilock);
3016 cmdresult = ddi_dma_mem_alloc(fdc->c_dmahandle, csb->csb_len,
3022 mutex_exit(&fdc->c_hilock);
3026 fdc->c_csb.csb_read = CSB_WRITE;
3027 if (fdstart_dma(fdc, fd, csb->csb_len) != 0) {
3029 mutex_exit(&fdc->c_hilock);
3032 mutex_exit(&fdc->c_hilock);
3050 if ((cmdresult = fdexec(fdc, FDXC_SLEEP | FDXC_CHECKCHG)) == 0) {
3055 if (fdc->c_fdtype & FDCTYPE_DMA) {
3061 fdretcsb(fdc);
3082 fdstart(struct fdctlr *fdc)
3106 bp = fdc->c_actf;
3110 fdc->c_actf = bp->av_forw;
3111 fdc->c_current = bp;
3127 unit = fdc->c_un->un_unit_no;
3128 un = fdc->c_un;
3151 fdgetcsb(fdc); /* get csb (maybe wait for it) */
3152 csb = &fdc->c_csb;
3169 if (((fdc->c_fdtype & FDCTYPE_SLAVIO) &&
3171 (fdc->c_fdtype & FDCTYPE_TCBUG))
3176 if (fdc->c_fdtype & FDCTYPE_TCBUG)
3184 fdc->c_csb.csb_read = CSB_READ;
3186 fdc->c_csb.csb_read = CSB_WRITE;
3251 if ((fdc->c_fdtype & FDCTYPE_SLAVIO) &&
3253 (fdc->c_csb.csb_read == CSB_READ)) {
3263 } else if (fdc->c_fdtype & FDCTYPE_TCBUG) {
3278 if (fdc->c_fdtype & FDCTYPE_SB) {
3301 if (fdc->c_fdtype & FDCTYPE_SB)
3307 if (fdc->c_fdtype & FDCTYPE_TCBUG)
3322 if (fdc->c_fdtype & FDCTYPE_DMA) {
3323 if ((fdc->c_fdtype & FDCTYPE_SB) &&
3327 csb->csb_addr = fdc->dma_buf;
3330 bcopy(addr, fdc->dma_buf, tlen);
3333 mutex_enter(&fdc->c_hilock);
3335 if (fdstart_dma(fdc, csb->csb_addr,
3341 mutex_exit(&fdc->c_hilock);
3347 mutex_exit(&fdc->c_hilock);
3351 bp->b_error = fdexec(fdc, FDXC_SLEEP|FDXC_CHECKCHG);
3378 if ((fdc->c_fdtype & FDCTYPE_SB) &&
3381 bcopy(fdc->dma_buf, addr, tlen);
3395 bp->b_resid, bp->b_bcount, fdc->c_csb.csb_rlen));
3397 fdc->c_current = 0;
3398 fdretcsb(fdc);
3415 bp = fdc->c_actf;
3426 fdstart_dma(struct fdctlr *fdc, caddr_t addr, uint_t len)
3433 if (fdc->c_csb.csb_read == CSB_READ) {
3451 bzero((char *)&fdc->c_csb.csb_dmacookie,
3452 sizeof (fdc->c_csb.csb_dmacookie));
3453 fdc->c_csb.csb_nwin = 0;
3454 fdc->c_csb.csb_windex = 0;
3455 fdc->c_csb.csb_ccount = 0;
3457 res = ddi_dma_addr_bind_handle(fdc->c_dmahandle, NULL, addr, len,
3458 flags, DDI_DMA_DONTWAIT, 0, &fdc->c_csb.csb_dmacookie,
3459 &fdc->c_csb.csb_ccount);
3470 fdc->c_csb.csb_nwin = 1;
3471 fdc->c_csb.csb_windex = 1;
3483 if (ddi_dma_numwin(fdc->c_dmahandle,
3484 &fdc->c_csb.csb_nwin) != DDI_SUCCESS) {
3491 fdc->c_csb.csb_nwin));
3497 fdc->c_csb.csb_windex = 1;
3527 ASSERT(fdc->c_csb.csb_dmacookie.dmac_size);
3539 fd_unbind_handle(struct fdctlr *fdc)
3541 if ((fdc->c_fdtype & FDCTYPE_DMA) &&
3542 ((fdc->c_csb.csb_read == CSB_READ) ||
3543 (fdc->c_csb.csb_read == CSB_WRITE))) {
3544 mutex_enter(&fdc->c_hilock);
3546 if (fdc->c_fdtype & FDCTYPE_SB) {
3547 if (fdc->sb_dma_lock) {
3548 release_sb_dma(fdc);
3558 if (get_data_count_register(fdc) != 0) {
3562 reset_dma_controller(fdc);
3563 set_dma_control_register(fdc, DCSR_INIT_BITS);
3566 if (ddi_dma_unbind_handle(fdc->c_dmahandle) != DDI_SUCCESS) {
3569 mutex_exit(&fdc->c_hilock);
3572 mutex_exit(&fdc->c_hilock);
3599 fdexec(struct fdctlr *fdc, int flags)
3605 caddr_t a = (caddr_t)fdc;
3609 ASSERT(mutex_owned(&fdc->c_lolock));
3611 csb = &fdc->c_csb;
3615 ASSERT(unit == fdc->c_un->un_unit_no);
3621 fdc->c_un->un_chars->fdc_transfer_rate));
3623 fdc->c_un->un_chars->fdc_sec_size));
3625 fdc->c_un->un_label.dkl_map[2].dkl_nblk));
3627 if ((fdc->c_fdtype & FDCTYPE_CTRLMASK) == FDCTYPE_82077) {
3628 fdexec_turn_on_motor(fdc, flags, unit);
3632 fdselect(fdc, unit, 1); /* select drive */
3637 switch (fdc->c_un->un_chars->fdc_transfer_rate) {
3639 Dsr(fdc, 0);
3642 Dsr(fdc, 1);
3645 Dsr(fdc, 2);
3655 if ((flags & FDXC_CHECKCHG) && fdsense_chng(fdc, unit)) {
3657 fdc->c_un->un_flags |= FDUNIT_CHANGED;
3659 if (fdcheckdisk(fdc, unit)) {
3661 (void) fd_unbind_handle(fdc);
3672 fdc->fdstats.rd++;
3675 fdc->fdstats.wr++;
3678 fdc->fdstats.recal++;
3681 fdc->fdstats.form++;
3684 fdc->fdstats.other++;
3713 if ((fdc->c_fdtype & FDCTYPE_DMA) &&
3714 ((fdc->c_csb.csb_read == CSB_READ) ||
3715 (fdc->c_csb.csb_read == CSB_WRITE))) {
3716 mutex_enter(&fdc->c_hilock);
3720 reset_dma_controller(fdc);
3723 (void *)fdc->c_csb.csb_dmacookie.dmac_laddress));
3726 fdc->c_csb.csb_dmacookie.dmac_size));
3727 ASSERT(fdc->c_csb.csb_dmacookie.dmac_size);
3729 set_data_count_register(fdc,
3730 fdc->c_csb.csb_dmacookie.dmac_size);
3731 set_data_address_register(fdc,
3732 fdc->c_csb.csb_dmacookie.dmac_laddress);
3736 if (fdc->c_csb.csb_read == CSB_READ)
3737 set_dma_mode(fdc, CSB_READ);
3739 set_dma_mode(fdc, CSB_WRITE);
3740 mutex_exit(&fdc->c_hilock);
3750 if (Msr(fdc) & CB) {
3753 (C, "fdc: unexpectedly busy-stat 0x%x\n", Msr(fdc)));
3756 (void) fd_unbind_handle(fdc);
3765 if ((Msr(fdc) & (DIO|RQM)) == RQM)
3770 (C, "fdc: no RQM - stat 0x%x\n", Msr(fdc)));
3773 (void) fd_unbind_handle(fdc);
3777 Set_Fifo(fdc, csb->csb_cmds[i]);
3781 Msr(fdc)));
3791 fdc->c_timeid = timeout(fdwatch, a,
3796 (C, "fdexec: cmd sent, Msr 0x%x\n", Msr(fdc)));
3800 if (fdc->c_fdtype & FDCTYPE_82077) {
3801 if (fdc->c_mtimeid == 0) {
3802 fdc->c_mtimeid = timeout(fdmotoff, a,
3814 if ((Msr(fdc) & (DIO|RQM)) == RQM)
3840 while ((tmp = Msr(fdc)) & CB) {
3846 Fifo(fdc);
3855 Msr(fdc), csb->csb_nrslts));
3858 if (fdc->c_fdtype & FDCTYPE_82077) {
3859 if (fdc->c_mtimeid == 0) {
3860 fdc->c_mtimeid = timeout(
3879 fdc->c_flags |= FDCFLG_WAITING;
3880 while (fdc->c_flags & FDCFLG_WAITING) {
3881 cv_wait(&fdc->c_iocv, &fdc->c_lolock);
3889 if ((fdc->c_fdtype & FDCTYPE_TCBUG) &&
3901 if (((csb->csb_rslt[0] & IC_SR0) || (fdc->c_csb.csb_dcsr_rslt) ||
3906 if (fdrecover(fdc) != 0) {
3907 if (fdc->c_fdtype & FDCTYPE_82077) {
3908 if (fdc->c_mtimeid == 0) {
3909 fdc->c_mtimeid = timeout(fdmotoff,
3919 (void) fd_unbind_handle(fdc);
3928 if (fdc->c_fdtype & FDCTYPE_82077) {
3929 if (fdc->c_mtimeid == 0) {
3930 fdc->c_mtimeid = timeout(fdmotoff, a, Motoff_delay);
3935 if (fd_unbind_handle(fdc))
3947 fdexec_turn_on_motor(struct fdctlr *fdc, int flags, uint_t unit)
3956 timeid = fdc->c_mtimeid;
3957 fdc->c_mtimeid = 0;
3959 mutex_exit(&fdc->c_lolock);
3961 mutex_enter(&fdc->c_lolock);
3964 ASSERT(fdc->c_un->un_unit_no == unit);
3967 set_rotational_speed(fdc, unit);
3969 if (!(Dor(fdc) & (MOTEN(unit)))) {
3977 Set_dor(fdc, (MOTEN(unit)), 1);
3981 (void) cv_timedwait(&fdc->c_motoncv,
3982 &fdc->c_lolock, local_lbolt + Moton_delay);
4000 fdrecover(struct fdctlr *fdc)
4005 csb = &fdc->c_csb;
4007 if (fdc->c_flags & FDCFLG_TIMEDOUT) {
4010 fdc->c_flags ^= FDCFLG_TIMEDOUT;
4017 savecsb = fdc->c_csb;
4018 bzero(&fdc->c_csb, sizeof (struct fdcsb));
4019 FDERRPRINT(FDEP_L1, FDEM_RECO, (C, "fdc: resetting\n"));
4021 (void) fdreset(fdc);
4023 if (fdc->c_fdtype & FDCTYPE_DMA) {
4024 mutex_enter(&fdc->c_hilock);
4026 reset_dma_controller(fdc);
4027 set_dma_control_register(fdc, DCSR_INIT_BITS);
4028 mutex_exit(&fdc->c_hilock);
4034 (void) fdrecalseek(fdc, savecsb.csb_unit, -1, 0);
4035 fdc->c_csb = savecsb; /* restore original csb */
4042 fdc->fdstats.de++;
4045 fdc->fdstats.run++;
4048 fdc->fdstats.bfmt++;
4051 fdc->fdstats.to++;
4102 (int)fdc->c_current->b_blkno));
4105 if (fdc->c_fdtype & FDCTYPE_SB) {
4157 struct fdctlr *fdc;
4171 fdc = fdctlrs;
4173 if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
4174 tmp_dcsr = get_dma_control_register(fdc);
4180 mutex_enter(&fdc->c_hilock);
4182 if (fdc->c_csb.csb_opmode == 0x0) {
4183 fdc->c_csb.csb_opmode = 2;
4185 if (fdc->sb_dma_lock) {
4186 release_sb_dma(fdc);
4195 switch (fdc->c_csb.csb_opmode) {
4215 fdc->c_csb.csb_nrslts = 0;
4232 while (((tmp = Msr(fdc)) & CB) &&
4241 fdc->c_csb.csb_rslt
4242 [fdc->c_csb.csb_nrslts++]
4243 = Fifo(fdc);
4248 fdc->c_csb.csb_rslt
4249 [fdc->c_csb.csb_nrslts
4257 fdc->c_csb.csb_status = 2;
4277 fdc->c_csb.csb_dcsr_rslt = 1;
4280 reset_dma_controller(fdc);
4281 set_dma_control_register(fdc, DCSR_INIT_BITS);
4286 if ((fdc->c_fdtype & FDCTYPE_TCBUG) &&
4287 ((fdc->c_csb.csb_rslt[0] & IC_SR0) == 0x40) &&
4288 (fdc->c_csb.csb_rslt[1] & EN_SR1)) {
4290 fdc->c_csb.csb_rslt[0] &= ~IC_SR0;
4292 fdc->c_csb.csb_rslt[1] &= ~EN_SR1;
4299 if (((fdc->c_csb.csb_rslt[0] & IC_SR0) != 0) ||
4300 (fdc->c_csb.csb_rslt[1] != 0) ||
4301 (fdc->c_csb.csb_rslt[2] != 0)) {
4313 get_data_count_register(fdc)));
4319 if (fdc->c_csb.csb_ccount == 0) {
4323 fdc->c_csb.csb_ccount--;
4324 ccount = fdc->c_csb.csb_ccount;
4326 windex = fdc->c_csb.csb_windex;
4333 if ((ccount == 0) && (windex == fdc->c_csb.csb_nwin)) {
4346 ddi_dma_nextcookie(fdc->c_dmahandle,
4347 &fdc->c_csb.csb_dmacookie);
4351 fdc->c_csb.csb_dmacookie.dmac_laddress));
4355 fdc->c_csb.csb_dmacookie.dmac_size));
4359 (void) ddi_dma_getwin(fdc->c_dmahandle,
4360 fdc->c_csb.csb_windex,
4362 &fdc->c_csb.csb_dmacookie,
4363 &fdc->c_csb.csb_ccount);
4364 fdc->c_csb.csb_windex++;
4368 fdc->c_csb.csb_windex));
4372 fdc->c_csb.csb_ccount));
4376 fdc->c_csb.csb_dmacookie.dmac_laddress));
4380 fdc->c_csb.csb_dmacookie.dmac_size));
4388 ASSERT(fdc->c_csb.csb_dmacookie.dmac_size);
4390 set_data_count_register(fdc,
4391 fdc->c_csb.csb_dmacookie.dmac_size);
4392 set_data_address_register(fdc,
4393 fdc->c_csb.csb_dmacookie.dmac_laddress);
4397 fdc->c_csb.csb_dmacookie.dmac_size));
4401 fdc->c_csb.csb_cmds[2] = fdc->c_csb.csb_rslt[3];
4402 fdc->c_csb.csb_cmds[3] = fdc->c_csb.csb_rslt[4];
4403 fdc->c_csb.csb_cmds[4] = fdc->c_csb.csb_rslt[5];
4404 fdc->c_csb.csb_cmds[1] = (fdc->c_csb.csb_cmds[1]
4405 & ~0x04) | (fdc->c_csb.csb_rslt[4] << 2);
4407 for (i = 0; i < (int)fdc->c_csb.csb_ncmds; i++) {
4414 if ((Msr(fdc) & (DIO|RQM)) == RQM)
4420 "fdc: no RQM - stat 0x%x\n",
4421 Msr(fdc)));
4423 fdc->c_csb.csb_status = 2;
4428 Set_Fifo(fdc, fdc->c_csb.csb_cmds[i]);
4433 fdc->c_csb.csb_cmds[i], Msr(fdc)));
4438 set_dma_control_register(fdc, tmp_dcsr |
4454 fdc->c_csb.csb_dcsr_rslt = 1;
4455 reset_dma_controller(fdc);
4456 set_dma_control_register(fdc, DCSR_INIT_BITS);
4476 while (((Msr(fdc) & CB)) && (i < 10000)) {
4489 while ((!(Msr(fdc) & RQM)) && (i < 10000)) {
4500 Set_Fifo(fdc, SNSISTAT);
4503 while ((!(Msr(fdc) & RQM)) && (i < 10000)) {
4511 fdc->c_csb.csb_rslt[0] = Fifo(fdc);
4514 while ((!(Msr(fdc) & RQM)) && (i < 10000)) {
4522 fdc->c_csb.csb_rslt[1] = Fifo(fdc);
4541 mutex_exit(&fdc->c_hilock);
4544 mutex_enter(&fdc->c_lolock);
4546 fdc->c_csb.csb_opmode = 0;
4551 if (fdc->c_timeid) {
4552 timeout_id_t timeid = fdc->c_timeid;
4553 fdc->c_timeid = 0;
4554 mutex_exit(&fdc->c_lolock);
4556 mutex_enter(&fdc->c_lolock);
4560 if (fdc->c_flags & FDCFLG_WAITING) {
4569 fdc->c_flags ^= FDCFLG_WAITING;
4570 cv_signal(&fdc->c_iocv);
4579 fdc->c_csb.csb_rslt[0], fdc->c_csb.csb_rslt[1],
4580 fdc->c_csb.csb_rslt[2]));
4582 mutex_exit(&fdc->c_lolock);
4585 if (fdc->c_intrstat)
4601 struct fdctlr *fdc = (struct fdctlr *)arg;
4604 csb = &fdc->c_csb;
4616 if (fdc->c_intrstat)
4621 mutex_enter(&fdc->c_lolock);
4625 if (fdc->c_timeid) {
4626 timeout_id_t timeid = fdc->c_timeid;
4627 fdc->c_timeid = 0;
4628 mutex_exit(&fdc->c_lolock);
4630 mutex_enter(&fdc->c_lolock);
4634 if (fdc->c_flags & FDCFLG_WAITING) {
4638 fdc->c_flags ^= FDCFLG_WAITING;
4639 cv_signal(&fdc->c_iocv);
4650 if (fdc->c_intrstat)
4652 mutex_exit(&fdc->c_lolock);
4663 struct fdctlr *fdc = arg;
4669 mutex_enter(&fdc->c_lolock);
4670 if (fdc->c_timeid == 0) {
4678 mutex_exit(&fdc->c_lolock);
4681 fdc->c_timeid = 0;
4682 csb = &fdc->c_csb;
4684 mutex_enter(&fdc->c_hilock);
4694 mutex_exit(&fdc->c_hilock);
4698 fdc->c_flags |= FDCFLG_TIMEDOUT;
4701 if ((fdc->c_fdtype & FDCTYPE_DMA) == 0) {
4702 ddi_trigger_softintr(fdc->c_softid);
4704 mutex_exit(&fdc->c_lolock);
4706 mutex_exit(&fdc->c_lolock);
4716 fdgetcsb(struct fdctlr *fdc)
4719 ASSERT(mutex_owned(&fdc->c_lolock));
4720 while (fdc->c_flags & FDCFLG_BUSY) {
4721 fdc->c_flags |= FDCFLG_WANT;
4722 cv_wait(&fdc->c_csbcv, &fdc->c_lolock);
4724 fdc->c_flags |= FDCFLG_BUSY; /* got it! */
4732 fdretcsb(struct fdctlr *fdc)
4735 ASSERT(mutex_owned(&fdc->c_lolock));
4737 fdc->c_flags &= ~FDCFLG_BUSY; /* let go */
4739 fdc->c_csb.csb_read = 0;
4741 if (fdc->c_flags & FDCFLG_WANT) {
4742 fdc->c_flags ^= FDCFLG_WANT;
4751 cv_broadcast(&fdc->c_csbcv);
4765 fdreset(struct fdctlr *fdc)
4773 ASSERT(mutex_owned(&fdc->c_lolock));
4776 fdc->fdstats.reset++;
4785 if ((fdc->c_fdtype & FDCTYPE_CTRLMASK) == FDCTYPE_82077) {
4796 timeid = fdc->c_mtimeid;
4797 fdc->c_mtimeid = 0;
4799 mutex_exit(&fdc->c_lolock);
4801 mutex_enter(&fdc->c_lolock);
4804 Set_dor(fdc, DMAGATE, 0);
4809 Dsr(fdc, SWR);
4820 Dsr(fdc, 0);
4822 switch (fdc->c_fdtype & FDCTYPE_CTRLMASK) {
4830 fdc->c_flags |= FDCFLG_WAITING;
4838 Set_dor(fdc, DMAGATE|RESET, 1);
4841 (C, "fdattach: Dor 0x%x\n", Dor(fdc)));
4844 if (cv_timedwait(&fdc->c_iocv, &fdc->c_lolock,
4851 fdc->c_flags |= FDCFLG_WAITING;
4857 cv_wait(&fdc->c_iocv, &fdc->c_lolock);
4860 csb = &fdc->c_csb;
4863 csb->csb_unit = fdc->c_un->un_unit_no;
4871 /* send SPECIFY command to fdc */
4875 if (fdc->c_fdtype & FDCTYPE_DMA)
4883 (void) fdexec(fdc, 0); /* no FDXC_CHECKCHG, ... */
4886 /* send CONFIGURE command to fdc */
4899 (void) fdexec(fdc, 0); /* no FDXC_CHECKCHG, ... */
4924 fdrecalseek(struct fdctlr *fdc, int unit, int arg, int execflg)
4929 ASSERT(fdc->c_un->un_unit_no == unit);
4935 csb = &fdc->c_csb;
4957 if (result = fdexec(fdc, FDXC_SLEEP | execflg)) {
4984 fdsensedrv(struct fdctlr *fdc, int unit)
4988 ASSERT(fdc->c_un->un_unit_no == unit);
4990 csb = &fdc->c_csb;
5004 (void) fdexec(fdc, 0); /* DON't check changed!, no sleep */
5020 fdcheckdisk(struct fdctlr *fdc, int unit)
5030 ASSERT(fdc->c_un->un_unit_no == unit);
5036 csb = &fdc->c_csb;
5037 savecsb = fdc->c_csb;
5047 st3 = fdsensedrv(fdc, unit);
5058 err = fdrecalseek(fdc, unit, seekto, 0);
5061 fdc->c_csb = savecsb;
5073 if (fdsense_chng(fdc, csb->csb_unit)) {
5089 fdselect(struct fdctlr *fdc, int unit, int on)
5092 ASSERT(fdc->c_un->un_unit_no == unit);
5097 switch (fdc->c_fdtype & FDCTYPE_AUXIOMASK) {
5105 (C, "fdselect: (before) Dor 0x%x\n", Dor(fdc)));
5108 Set_dor(fdc, DRVSEL, !on);
5110 Set_dor(fdc, DRVSEL, on);
5114 (C, "fdselect: Dor 0x%x\n", Dor(fdc)));
5125 fdeject(struct fdctlr *fdc, int unit)
5129 ASSERT(fdc->c_un->un_unit_no == unit);
5131 un = fdc->c_un;
5138 switch (fdc->c_fdtype & FDCTYPE_AUXIOMASK) {
5146 if (!(Dor(fdc) & MOTEN(unit))) {
5148 Set_dor(fdc, MOTEN(unit), 1);
5152 Set_dor(fdc, EJECT, 1);
5155 Set_dor(fdc, EJECT, 0);
5158 if (!(Dor(fdc) & MOTEN(unit))) {
5160 Set_dor(fdc, MOTEN(unit), 1);
5164 Set_dor(fdc, EJECT_DMA, 1);
5167 Set_dor(fdc, EJECT_DMA, 0);
5178 fdsense_chng(struct fdctlr *fdc, int unit)
5184 ASSERT(fdc->c_un->un_unit_no == unit);
5194 if (Dir(fdc) & DSKCHG)
5202 switch (fdc->c_fdtype & FDCTYPE_AUXIOMASK) {
5204 if (*fdc->c_auxiova & AUX_DISKCHG)
5211 if (!(Dor(fdc) & MOTEN(unit))) {
5213 Set_dor(fdc, MOTEN(unit), 1);
5216 if (Dir(fdc) & DSKCHG)
5236 fdgetlabel(struct fdctlr *fdc, int unit)
5250 un = fdc->c_un;
5253 ASSERT(fdc->c_un->un_unit_no == unit);
5304 if (!(err = fdrw(fdc, unit, FDREAD, 0, 0,
5308 fdrw(fdc, unit, FDREAD, 0, 0,
5312 !(err = fdrw(fdc, unit, FDREAD, 0, 0, 1, (caddr_t)label,
5440 fdrw(struct fdctlr *fdc, int unit, int rw, int cyl, int head,
5454 ASSERT(fdc->c_un->un_unit_no == unit);
5456 CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc);
5458 if (fdc->c_un->un_state == FD_STATE_STOPPED) {
5459 mutex_exit(&fdc->c_lolock);
5460 if ((pm_raise_power(fdc->c_dip, 0, PM_LEVEL_ON))
5464 mutex_enter(&fdc->c_lolock);
5468 mutex_enter(&fdc->c_lolock);
5471 fdgetcsb(fdc);
5472 csb = &fdc->c_csb;
5473 ch = fdc->c_un->un_chars;
5475 if (fdc->c_fdtype & FDCTYPE_TCBUG) {
5483 if (fdc->c_fdtype & FDCTYPE_TCBUG) {
5493 fdc->c_csb.csb_read = CSB_READ;
5495 fdc->c_csb.csb_read = CSB_WRITE;
5500 if (fdc->c_fdtype & FDCTYPE_SB)
5509 if (fdc->c_fdtype & FDCTYPE_TCBUG)
5513 (uchar_t)max(fdc->c_un->un_chars->fdc_secptrack, sector);
5526 if (fdc->c_fdtype & FDCTYPE_DMA) {
5528 mutex_enter(&fdc->c_hilock);
5534 res = ddi_dma_mem_alloc(fdc->c_dmahandle, len,
5543 fdretcsb(fdc);
5544 mutex_exit(&fdc->c_hilock);
5550 if (fdstart_dma(fdc, dma_addr, len) != 0) {
5551 fdretcsb(fdc);
5553 mutex_exit(&fdc->c_hilock);
5563 if (fdc->c_csb.csb_read == CSB_WRITE) {
5568 mutex_exit(&fdc->c_hilock);
5576 if (fdexec(fdc, FDXC_SLEEP | FDXC_CHECKCHG) != 0) {
5577 fdretcsb(fdc);
5592 if (fdc->c_fdtype & FDCTYPE_DMA) {
5593 if (fdc->c_csb.csb_read == CSB_READ) {
5602 fdretcsb(fdc);
5635 struct fdctlr *fdc = fdctlrs;
5638 while (fdc) {
5639 if (ddi_get_instance(fdc->c_dip) == ctlr)
5640 return (fdc);
5641 fdc = fdc->c_next;
5643 return (fdc);
5931 set_rotational_speed(struct fdctlr *fdc, int unit)
5936 ASSERT(fdc->c_un->un_unit_no == unit);
5941 if (fdc->c_fdtype & FDCTYPE_MACHIO)
5955 is_medium = fdc->c_un->un_chars->fdc_medium;
5957 if (fdc->c_un->un_flags & FDUNIT_SET_SPEED) {
5961 ((fdc->c_un->un_flags & FDUNIT_MEDIUM) ? 1 : 0);
5966 fdc->c_un->un_flags ^= FDUNIT_MEDIUM;
5969 fdc->c_un->un_flags &= ~FDUNIT_SET_SPEED;
5974 fdselect(fdc, unit, 0);
5977 if ((fdc->c_fdtype & FDCTYPE_AUXIOMASK) == FDCTYPE_SLAVIO) {
5978 Set_dor(fdc, MEDIUM_DENSITY, is_medium);
5981 if ((fdc->c_fdtype & FDCTYPE_AUXIOMASK) == FDCTYPE_CHEERIO) {
5983 Set_auxio(fdc, AUX_MEDIUM_DENSITY);
5985 Set_auxio(fdc, AUX_HIGH_DENSITY);
5994 fdselect(fdc, unit, 1); /* Sony requirement */
6005 struct fdctlr *fdc;
6009 fdc = fd_getctlr(dev);
6010 unit = fdc->c_un->un_unit_no;
6011 un = fdc->c_un;
6013 mutex_enter(&fdc->c_lolock);
6020 mutex_exit(&fdc->c_lolock);
6025 un->un_media_state = fd_get_media_state(fdc, unit);
6026 cv_broadcast(&fdc->c_statecv);
6028 mutex_exit(&fdc->c_lolock);
6037 fd_get_media_state(struct fdctlr *fdc, int unit)
6041 ASSERT(fdc->c_un->un_unit_no == unit);
6043 if (fdsense_chng(fdc, unit)) {
6045 if (fdcheckdisk(fdc, unit)) {
6060 struct fdctlr *fdc;
6065 fdc = fd_getctlr(dev);
6066 unit = fdc->c_un->un_unit_no;
6067 un = fdc->c_un;
6069 mutex_enter(&fdc->c_lolock);
6071 CHECK_AND_WAIT_FD_STATE_SUSPENDED(fdc);
6073 if (fdc->c_un->un_state == FD_STATE_STOPPED) {
6074 mutex_exit(&fdc->c_lolock);
6075 if ((pm_raise_power(fdc->c_dip, 0, PM_LEVEL_ON))
6080 (void) pm_idle_component(fdc->c_dip, 0);
6084 mutex_enter(&fdc->c_lolock);
6087 un->un_media_state = fd_get_media_state(fdc, unit);
6095 if (cv_wait_sig(&fdc->c_statecv, &fdc->c_lolock) == 0) {
6097 mutex_exit(&fdc->c_lolock);
6106 mutex_exit(&fdc->c_lolock);
6108 mutex_enter(&fdc->c_lolock);
6112 if (fdgetlabel(fdc, unit)) {
6113 mutex_exit(&fdc->c_lolock);
6117 mutex_exit(&fdc->c_lolock);
6155 struct fdctlr *fdc;
6165 fdc = fd_getctlr(instance << FDINSTSHIFT);
6166 if (fdc->c_un == NULL)
6170 rval = fd_pm_lower_power(fdc);
6173 rval = fd_pm_raise_power(fdc);
6187 fd_pm_lower_power(struct fdctlr *fdc)
6190 mutex_enter(&fdc->c_lolock);
6192 if ((fdc->c_un->un_state == FD_STATE_SUSPENDED) ||
6193 (fdc->c_un->un_state == FD_STATE_STOPPED)) {
6194 mutex_exit(&fdc->c_lolock);
6202 if (fdc->c_flags & FDCFLG_BUSY) {
6205 mutex_exit(&fdc->c_lolock);
6209 fdc->c_un->un_state = FD_STATE_STOPPED;
6211 mutex_exit(&fdc->c_lolock);
6223 fd_pm_raise_power(struct fdctlr *fdc)
6226 struct fdunit *un = fdc->c_un;
6230 mutex_enter(&fdc->c_lolock);
6231 fdgetcsb(fdc);
6234 if (fdc->c_fdtype & FDCTYPE_DMA) {
6235 mutex_enter(&fdc->c_hilock);
6236 reset_dma_controller(fdc);
6237 set_dma_control_register(fdc, DCSR_INIT_BITS);
6238 mutex_exit(&fdc->c_hilock);
6246 fdc->c_un->un_flags |= FDUNIT_SET_SPEED;
6249 (void) fdreset(fdc);
6251 unit = fdc->c_un->un_unit_no;
6254 if (fdrecalseek(fdc, unit, -1, 0) != 0) {
6257 fdretcsb(fdc);
6258 mutex_exit(&fdc->c_lolock);
6263 fdselect(fdc, unit, 0);
6265 fdretcsb(fdc);
6266 mutex_exit(&fdc->c_lolock);
6288 * set_data_count_register(struct fdctlr *fdc, uint32_t count)
6293 set_data_count_register(struct fdctlr *fdc, uint32_t count)
6295 if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
6297 dma_reg = (struct cheerio_dma_reg *)fdc->c_dma_regs;
6298 ddi_put32(fdc->c_handlep_dma, &dma_reg->fdc_dbcr, count);
6299 } else if (fdc->c_fdtype & FDCTYPE_SB) {
6302 dma_reg = (struct sb_dma_reg *)fdc->c_dma_regs;
6303 switch (fdc->sb_dma_channel) {
6305 ddi_put16(fdc->c_handlep_dma,
6310 ddi_put16(fdc->c_handlep_dma,
6315 ddi_put16(fdc->c_handlep_dma,
6320 ddi_put16(fdc->c_handlep_dma,
6327 fdc->sb_dma_channel));
6334 * get_data_count_register(struct fdctlr *fdc)
6339 get_data_count_register(struct fdctlr *fdc)
6342 if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
6344 dma_reg = (struct cheerio_dma_reg *)fdc->c_dma_regs;
6345 retval = ddi_get32(fdc->c_handlep_dma, &dma_reg->fdc_dbcr);
6346 } else if (fdc->c_fdtype & FDCTYPE_SB) {
6348 dma_reg = (struct sb_dma_reg *)fdc->c_dma_regs;
6349 switch (fdc->sb_dma_channel) {
6351 retval = ddi_get16(fdc->c_handlep_dma,
6355 retval = ddi_get16(fdc->c_handlep_dma,
6359 retval = ddi_get16(fdc->c_handlep_dma,
6363 retval = ddi_get16(fdc->c_handlep_dma,
6369 fdc->sb_dma_channel));
6380 * reset_dma_controller(struct fdctlr *fdc)
6385 reset_dma_controller(struct fdctlr *fdc)
6387 if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
6389 dma_reg = (struct cheerio_dma_reg *)fdc->c_dma_regs;
6390 ddi_put32(fdc->c_handlep_dma, &dma_reg->fdc_dcsr, DCSR_RESET);
6391 while (get_dma_control_register(fdc) & DCSR_CYC_PEND)
6393 ddi_put32(fdc->c_handlep_dma, &dma_reg->fdc_dcsr, 0);
6394 } else if (fdc->c_fdtype & FDCTYPE_SB) {
6396 dma_reg = (struct sb_dma_reg *)fdc->c_dma_regs;
6397 ddi_put8(fdc->c_handlep_dma, &dma_reg->sb_dma_regs[DMAC1_MASK],
6398 (fdc->sb_dma_channel & 0x3));
6409 get_dma_control_register(struct fdctlr *fdc)
6412 if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
6414 dma_reg = (struct cheerio_dma_reg *)fdc->c_dma_regs;
6415 retval = ddi_get32(fdc->c_handlep_dma, &dma_reg->fdc_dcsr);
6423 * set_data_address_register(struct fdctlr *fdc)
6427 set_data_address_register(struct fdctlr *fdc, uint32_t address)
6429 if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
6431 dma_reg = (struct cheerio_dma_reg *)fdc->c_dma_regs;
6432 ddi_put32(fdc->c_handlep_dma, &dma_reg->fdc_dacr, address);
6433 } else if (fdc->c_fdtype & FDCTYPE_SB) {
6435 dma_reg = (struct sb_dma_reg *)fdc->c_dma_regs;
6436 switch (fdc->sb_dma_channel) {
6438 ddi_put8(fdc->c_handlep_dma,
6441 ddi_put8(fdc->c_handlep_dma,
6444 ddi_put16(fdc->c_handlep_dma,
6449 ddi_put8(fdc->c_handlep_dma,
6452 ddi_put8(fdc->c_handlep_dma,
6455 ddi_put16(fdc->c_handlep_dma,
6460 ddi_put8(fdc->c_handlep_dma,
6463 ddi_put8(fdc->c_handlep_dma,
6466 ddi_put16(fdc->c_handlep_dma,
6471 ddi_put8(fdc->c_handlep_dma,
6474 ddi_put8(fdc->c_handlep_dma,
6477 ddi_put16(fdc->c_handlep_dma,
6484 fdc->sb_dma_channel));
6493 * set_dma_mode(struct fdctlr *fdc, int val)
6497 set_dma_mode(struct fdctlr *fdc, int val)
6499 if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
6501 dma_reg = (struct cheerio_dma_reg *)fdc->c_dma_regs;
6503 ddi_put32(fdc->c_handlep_dma, &dma_reg->fdc_dcsr,
6506 ddi_put32(fdc->c_handlep_dma, &dma_reg->fdc_dcsr,
6509 } else if (fdc->c_fdtype & FDCTYPE_SB) {
6512 dma_reg = (struct sb_dma_reg *)fdc->c_dma_regs;
6515 mode_reg_val = fdc->sb_dma_channel | DMAMODE_READ
6518 mode_reg_val = fdc->sb_dma_channel | DMAMODE_WRITE
6521 ddi_put8(fdc->c_handlep_dma, &dma_reg->sb_dma_regs[DMAC1_MODE],
6523 chn_mask = 1 << (fdc->sb_dma_channel & 0x3);
6524 ddi_put8(fdc->c_handlep_dma,
6526 fdc->sb_dma_lock = 1;
6537 set_dma_control_register(struct fdctlr *fdc, uint32_t val)
6539 if (fdc->c_fdtype & FDCTYPE_CHEERIO) {
6541 dma_reg = (struct cheerio_dma_reg *)fdc->c_dma_regs;
6542 ddi_put32(fdc->c_handlep_dma, &dma_reg->fdc_dcsr, val);
6547 release_sb_dma(struct fdctlr *fdc)
6550 dma_reg = (struct sb_dma_reg *)fdc->c_dma_regs;
6552 ddi_put8(fdc->c_handlep_dma,
6554 fdc->sb_dma_lock = 0;
6558 quiesce_fd_interrupt(struct fdctlr *fdc)
6570 if (fdc->c_fdtype & FDCTYPE_SB) {
6571 ddi_put8(fdc->c_handlep_cont, ((uint8_t *)fdc->c_dor),
6574 ddi_put8(fdc->c_handlep_cont, ((uint8_t *)fdc->c_dor),
6577 Set_Fifo(fdc, 0xE6);