floppy.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:22k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: floppy.h,v 1.32 2001/10/26 17:59:36 davem Exp $
  2.  * asm-sparc64/floppy.h: Sparc specific parts of the Floppy driver.
  3.  *
  4.  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  5.  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  6.  *
  7.  * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be)
  8.  */
  9. #ifndef __ASM_SPARC64_FLOPPY_H
  10. #define __ASM_SPARC64_FLOPPY_H
  11. #include <linux/config.h>
  12. #include <linux/init.h>
  13. #include <asm/page.h>
  14. #include <asm/pgtable.h>
  15. #include <asm/system.h>
  16. #include <asm/idprom.h>
  17. #include <asm/oplib.h>
  18. #include <asm/auxio.h>
  19. #include <asm/sbus.h>
  20. #include <asm/irq.h>
  21. /*
  22.  * Define this to enable exchanging drive 0 and 1 if only drive 1 is
  23.  * probed on PCI machines.
  24.  */
  25. #undef PCI_FDC_SWAP_DRIVES
  26. /* References:
  27.  * 1) Netbsd Sun floppy driver.
  28.  * 2) NCR 82077 controller manual
  29.  * 3) Intel 82077 controller manual
  30.  */
  31. struct sun_flpy_controller {
  32. volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
  33. volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
  34. volatile unsigned char dor_82077;     /* Digital Output reg. */
  35. volatile unsigned char tapectl_82077; /* Tape Control reg */
  36. volatile unsigned char status_82077;  /* Main Status Register. */
  37. #define drs_82077              status_82077   /* Digital Rate Select reg. */
  38. volatile unsigned char data_82077;    /* Data fifo. */
  39. volatile unsigned char ___unused;
  40. volatile unsigned char dir_82077;     /* Digital Input reg. */
  41. #define dcr_82077              dir_82077      /* Config Control reg. */
  42. };
  43. /* You'll only ever find one controller on an Ultra anyways. */
  44. static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
  45. unsigned long fdc_status;
  46. static struct sbus_dev *floppy_sdev = NULL;
  47. struct sun_floppy_ops {
  48. unsigned char (*fd_inb) (unsigned long port);
  49. void (*fd_outb) (unsigned char value, unsigned long port);
  50. void (*fd_enable_dma) (void);
  51. void (*fd_disable_dma) (void);
  52. void (*fd_set_dma_mode) (int);
  53. void (*fd_set_dma_addr) (char *);
  54. void (*fd_set_dma_count) (int);
  55. unsigned int (*get_dma_residue) (void);
  56. void (*fd_enable_irq) (void);
  57. void (*fd_disable_irq) (void);
  58. int (*fd_request_irq) (void);
  59. void (*fd_free_irq) (void);
  60. int (*fd_eject) (int);
  61. };
  62. static struct sun_floppy_ops sun_fdops;
  63. #define fd_inb(port)              sun_fdops.fd_inb(port)
  64. #define fd_outb(value,port)       sun_fdops.fd_outb(value,port)
  65. #define fd_enable_dma()           sun_fdops.fd_enable_dma()
  66. #define fd_disable_dma()          sun_fdops.fd_disable_dma()
  67. #define fd_request_dma()          (0) /* nothing... */
  68. #define fd_free_dma()             /* nothing... */
  69. #define fd_clear_dma_ff()         /* nothing... */
  70. #define fd_set_dma_mode(mode)     sun_fdops.fd_set_dma_mode(mode)
  71. #define fd_set_dma_addr(addr)     sun_fdops.fd_set_dma_addr(addr)
  72. #define fd_set_dma_count(count)   sun_fdops.fd_set_dma_count(count)
  73. #define get_dma_residue(x)        sun_fdops.get_dma_residue()
  74. #define fd_enable_irq()           sun_fdops.fd_enable_irq()
  75. #define fd_disable_irq()          sun_fdops.fd_disable_irq()
  76. #define fd_cacheflush(addr, size) /* nothing... */
  77. #define fd_request_irq()          sun_fdops.fd_request_irq()
  78. #define fd_free_irq()             sun_fdops.fd_free_irq()
  79. #define fd_eject(drive)           sun_fdops.fd_eject(drive)
  80. static int FLOPPY_MOTOR_MASK = 0x10;
  81. /* Super paranoid... */
  82. #undef HAVE_DISABLE_HLT
  83. static int sun_floppy_types[2] = { 0, 0 };
  84. /* Here is where we catch the floppy driver trying to initialize,
  85.  * therefore this is where we call the PROM device tree probing
  86.  * routine etc. on the Sparc.
  87.  */
  88. #define FLOPPY0_TYPE sun_floppy_init()
  89. #define FLOPPY1_TYPE sun_floppy_types[1]
  90. #define FDC1 ((unsigned long)sun_fdc)
  91. #define N_FDC    1
  92. #define N_DRIVE  8
  93. /* No 64k boundary crossing problems on the Sparc. */
  94. #define CROSS_64KB(a,s) (0)
  95. static unsigned char sun_82077_fd_inb(unsigned long port)
  96. {
  97. udelay(5);
  98. switch(port & 7) {
  99. default:
  100. printk("floppy: Asked to read unknown port %lxn", port);
  101. panic("floppy: Port bolixed.");
  102. case 4: /* FD_STATUS */
  103. return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
  104. case 5: /* FD_DATA */
  105. return sbus_readb(&sun_fdc->data_82077);
  106. case 7: /* FD_DIR */
  107. /* XXX: Is DCL on 0x80 in sun4m? */
  108. return sbus_readb(&sun_fdc->dir_82077);
  109. };
  110. panic("sun_82072_fd_inb: How did I get here?");
  111. }
  112. static void sun_82077_fd_outb(unsigned char value, unsigned long port)
  113. {
  114. udelay(5);
  115. switch(port & 7) {
  116. default:
  117. printk("floppy: Asked to write to unknown port %lxn", port);
  118. panic("floppy: Port bolixed.");
  119. case 2: /* FD_DOR */
  120. /* Happily, the 82077 has a real DOR register. */
  121. sbus_writeb(value, &sun_fdc->dor_82077);
  122. break;
  123. case 5: /* FD_DATA */
  124. sbus_writeb(value, &sun_fdc->data_82077);
  125. break;
  126. case 7: /* FD_DCR */
  127. sbus_writeb(value, &sun_fdc->dcr_82077);
  128. break;
  129. case 4: /* FD_STATUS */
  130. sbus_writeb(value, &sun_fdc->status_82077);
  131. break;
  132. };
  133. return;
  134. }
  135. /* For pseudo-dma (Sun floppy drives have no real DMA available to
  136.  * them so we must eat the data fifo bytes directly ourselves) we have
  137.  * three state variables.  doing_pdma tells our inline low-level
  138.  * assembly floppy interrupt entry point whether it should sit and eat
  139.  * bytes from the fifo or just transfer control up to the higher level
  140.  * floppy interrupt c-code.  I tried very hard but I could not get the
  141.  * pseudo-dma to work in c-code without getting many overruns and
  142.  * underruns.  If non-zero, doing_pdma encodes the direction of
  143.  * the transfer for debugging.  1=read 2=write
  144.  */
  145. char *pdma_vaddr;
  146. unsigned long pdma_size;
  147. volatile int doing_pdma = 0;
  148. /* This is software state */
  149. char *pdma_base = 0;
  150. unsigned long pdma_areasize;
  151. /* Common routines to all controller types on the Sparc. */
  152. static void sun_fd_disable_dma(void)
  153. {
  154. doing_pdma = 0;
  155. if (pdma_base) {
  156. mmu_unlockarea(pdma_base, pdma_areasize);
  157. pdma_base = 0;
  158. }
  159. }
  160. static void sun_fd_set_dma_mode(int mode)
  161. {
  162. switch(mode) {
  163. case DMA_MODE_READ:
  164. doing_pdma = 1;
  165. break;
  166. case DMA_MODE_WRITE:
  167. doing_pdma = 2;
  168. break;
  169. default:
  170. printk("Unknown dma mode %dn", mode);
  171. panic("floppy: Giving up...");
  172. }
  173. }
  174. static void sun_fd_set_dma_addr(char *buffer)
  175. {
  176. pdma_vaddr = buffer;
  177. }
  178. static void sun_fd_set_dma_count(int length)
  179. {
  180. pdma_size = length;
  181. }
  182. static void sun_fd_enable_dma(void)
  183. {
  184. pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
  185. pdma_base = pdma_vaddr;
  186. pdma_areasize = pdma_size;
  187. }
  188. /* Our low-level entry point in arch/sparc/kernel/entry.S */
  189. extern void floppy_hardint(int irq, void *unused, struct pt_regs *regs);
  190. static int sun_fd_request_irq(void)
  191. {
  192. static int once = 0;
  193. int error;
  194. if(!once) {
  195. once = 1;
  196. error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, 
  197.  SA_INTERRUPT, "floppy", NULL);
  198. return ((error == 0) ? 0 : -1);
  199. }
  200. return 0;
  201. }
  202. static void sun_fd_enable_irq(void)
  203. {
  204. }
  205. static void sun_fd_disable_irq(void)
  206. {
  207. }
  208. static void sun_fd_free_irq(void)
  209. {
  210. }
  211. static unsigned int sun_get_dma_residue(void)
  212. {
  213. /* XXX This isn't really correct. XXX */
  214. return 0;
  215. }
  216. static int sun_fd_eject(int drive)
  217. {
  218. set_dor(0x00, 0xff, 0x90);
  219. udelay(500);
  220. set_dor(0x00, 0x6f, 0x00);
  221. udelay(500);
  222. return 0;
  223. }
  224. #ifdef CONFIG_PCI
  225. #include <asm/ebus.h>
  226. #include <asm/isa.h>
  227. #include <asm/ns87303.h>
  228. static struct linux_ebus_dma *sun_pci_fd_ebus_dma;
  229. static struct pci_dev *sun_pci_ebus_dev;
  230. static int sun_pci_broken_drive = -1;
  231. struct sun_pci_dma_op {
  232. unsigned int  addr;
  233. int len;
  234. int direction;
  235. char *buf;
  236. };
  237. static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
  238. static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
  239. extern void floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
  240. static unsigned char sun_pci_fd_inb(unsigned long port)
  241. {
  242. udelay(5);
  243. return inb(port);
  244. }
  245. static void sun_pci_fd_outb(unsigned char val, unsigned long port)
  246. {
  247. udelay(5);
  248. outb(val, port);
  249. }
  250. static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
  251. {
  252. udelay(5);
  253. /*
  254.  * XXX: Due to SUN's broken floppy connector on AX and AXi
  255.  *      we need to turn on MOTOR_0 also, if the floppy is
  256.  *      jumpered to DS1 (like most PC floppies are). I hope
  257.  *      this does not hurt correct hardware like the AXmp.
  258.  *      (Eddie, Sep 12 1998).
  259.  */
  260. if (port == ((unsigned long)sun_fdc) + 2) {
  261. if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
  262. val |= 0x10;
  263. }
  264. }
  265. outb(val, port);
  266. }
  267. #ifdef PCI_FDC_SWAP_DRIVES
  268. static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
  269. {
  270. udelay(5);
  271. /*
  272.  * XXX: Due to SUN's broken floppy connector on AX and AXi
  273.  *      we need to turn on MOTOR_0 also, if the floppy is
  274.  *      jumpered to DS1 (like most PC floppies are). I hope
  275.  *      this does not hurt correct hardware like the AXmp.
  276.  *      (Eddie, Sep 12 1998).
  277.  */
  278. if (port == ((unsigned long)sun_fdc) + 2) {
  279. if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
  280. val &= ~(0x03);
  281. val |= 0x21;
  282. }
  283. }
  284. outb(val, port);
  285. }
  286. #endif /* PCI_FDC_SWAP_DRIVES */
  287. static void sun_pci_fd_reset_dma(void)
  288. {
  289. unsigned int dcsr;
  290. writel(EBUS_DCSR_RESET, &sun_pci_fd_ebus_dma->dcsr);
  291. udelay(1);
  292. dcsr = EBUS_DCSR_BURST_SZ_16 | EBUS_DCSR_TCI_DIS |
  293.        EBUS_DCSR_EN_CNT;
  294. writel(dcsr, (unsigned long)&sun_pci_fd_ebus_dma->dcsr);
  295. }
  296. static void sun_pci_fd_enable_dma(void)
  297. {
  298. unsigned int dcsr;
  299. if((NULL == sun_pci_dma_pending.buf)  ||
  300.    (0 == sun_pci_dma_pending.len)  ||
  301.    (0 == sun_pci_dma_pending.direction)) {
  302. goto enable; /* TODO: BUG() */
  303. }
  304. sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
  305. sun_pci_dma_current.len = sun_pci_dma_pending.len;
  306. sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
  307. sun_pci_dma_pending.buf  = NULL;
  308. sun_pci_dma_pending.len  = 0;
  309. sun_pci_dma_pending.direction = 0;
  310. sun_pci_dma_pending.addr = -1U;
  311. sun_pci_dma_current.addr = 
  312. pci_map_single( sun_pci_ebus_dev,
  313. sun_pci_dma_current.buf,
  314. sun_pci_dma_current.len,
  315. sun_pci_dma_current.direction);
  316. writel(sun_pci_dma_current.addr, &sun_pci_fd_ebus_dma->dacr);
  317. enable:
  318. dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
  319. dcsr |= EBUS_DCSR_EN_DMA;
  320. writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
  321. }
  322. static void sun_pci_fd_disable_dma(void)
  323. {
  324. unsigned int dcsr;
  325. dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
  326. if (dcsr & EBUS_DCSR_EN_DMA) {
  327. while (dcsr & EBUS_DCSR_DRAIN) {
  328. udelay(1);
  329. dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
  330. }
  331. dcsr &= ~(EBUS_DCSR_EN_DMA);
  332. writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
  333. if (dcsr & EBUS_DCSR_ERR_PEND) {
  334. sun_pci_fd_reset_dma();
  335. dcsr &= ~(EBUS_DCSR_ERR_PEND);
  336. writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
  337. }
  338. }
  339. if (sun_pci_dma_current.addr != -1U)
  340. pci_unmap_single(sun_pci_ebus_dev,
  341.  sun_pci_dma_current.addr,
  342.  sun_pci_dma_current.len,
  343.  sun_pci_dma_current.direction);
  344. sun_pci_dma_current.addr = -1U;
  345. }
  346. static void sun_pci_fd_set_dma_mode(int mode)
  347. {
  348. unsigned int dcsr;
  349. dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
  350. if (readl(&sun_pci_fd_ebus_dma->dbcr)) {
  351. sun_pci_fd_reset_dma();
  352. writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
  353. }
  354. dcsr |= EBUS_DCSR_EN_CNT | EBUS_DCSR_TC;
  355. /*
  356.  * For EBus WRITE means to system memory, which is
  357.  * READ for us.
  358.  */
  359. if (mode == DMA_MODE_WRITE) {
  360. dcsr &= ~(EBUS_DCSR_WRITE);
  361. sun_pci_dma_pending.direction = PCI_DMA_TODEVICE;
  362. } else {
  363. dcsr |= EBUS_DCSR_WRITE;
  364. sun_pci_dma_pending.direction = PCI_DMA_FROMDEVICE;
  365. }
  366. writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
  367. }
  368. static void sun_pci_fd_set_dma_count(int length)
  369. {
  370. sun_pci_dma_pending.len = length;
  371. writel(length, &sun_pci_fd_ebus_dma->dbcr);
  372. }
  373. static void sun_pci_fd_set_dma_addr(char *buffer)
  374. {
  375. sun_pci_dma_pending.buf = buffer;
  376. }
  377. static unsigned int sun_pci_get_dma_residue(void)
  378. {
  379. unsigned int dcsr, res;
  380. res = readl(&sun_pci_fd_ebus_dma->dbcr);
  381. if (res != 0) {
  382. dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
  383. sun_pci_fd_reset_dma();
  384. writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
  385. }
  386. return res;
  387. }
  388. static void sun_pci_fd_enable_irq(void)
  389. {
  390. unsigned int dcsr;
  391. dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
  392. dcsr |= EBUS_DCSR_INT_EN;
  393. writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
  394. }
  395. static void sun_pci_fd_disable_irq(void)
  396. {
  397. unsigned int dcsr;
  398. dcsr = readl(&sun_pci_fd_ebus_dma->dcsr);
  399. dcsr &= ~(EBUS_DCSR_INT_EN);
  400. writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
  401. }
  402. static int sun_pci_fd_request_irq(void)
  403. {
  404. int err;
  405. err = request_irq(FLOPPY_IRQ, floppy_interrupt, SA_SHIRQ,
  406.   "floppy", sun_fdc);
  407. if (err)
  408. return -1;
  409. sun_pci_fd_enable_irq();
  410. return 0;
  411. }
  412. static void sun_pci_fd_free_irq(void)
  413. {
  414. sun_pci_fd_disable_irq();
  415. free_irq(FLOPPY_IRQ, sun_fdc);
  416. }
  417. static int sun_pci_fd_eject(int drive)
  418. {
  419. return -EINVAL;
  420. }
  421. /*
  422.  * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
  423.  * even if this is configured using DS1, thus looks like /dev/fd1 with
  424.  * the cabling used in Ultras.
  425.  */
  426. #define DOR (port + 2)
  427. #define MSR (port + 4)
  428. #define FIFO (port + 5)
  429. static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
  430.         unsigned long reg)
  431. {
  432. unsigned char status;
  433. int timeout = 1000;
  434. while (!((status = inb(MSR)) & 0x80) && --timeout)
  435. udelay(100);
  436. outb(val, reg);
  437. }
  438. static unsigned char sun_pci_fd_sensei(unsigned long port)
  439. {
  440. unsigned char result[2] = { 0x70, 0x00 };
  441. unsigned char status;
  442. int i = 0;
  443. sun_pci_fd_out_byte(port, 0x08, FIFO);
  444. do {
  445. int timeout = 1000;
  446. while (!((status = inb(MSR)) & 0x80) && --timeout)
  447. udelay(100);
  448. if (!timeout)
  449. break;
  450. if ((status & 0xf0) == 0xd0)
  451. result[i++] = inb(FIFO);
  452. else
  453. break;
  454. } while (i < 2);
  455. return result[0];
  456. }
  457. static void sun_pci_fd_reset(unsigned long port)
  458. {
  459. unsigned char mask = 0x00;
  460. unsigned char status;
  461. int timeout = 10000;
  462. outb(0x80, MSR);
  463. do {
  464. status = sun_pci_fd_sensei(port);
  465. if ((status & 0xc0) == 0xc0)
  466. mask |= 1 << (status & 0x03);
  467. else
  468. udelay(100);
  469. } while ((mask != 0x0f) && --timeout);
  470. }
  471. static int sun_pci_fd_test_drive(unsigned long port, int drive)
  472. {
  473. unsigned char status, data;
  474. int timeout = 1000;
  475. int ready;
  476. sun_pci_fd_reset(port);
  477. data = (0x10 << drive) | 0x0c | drive;
  478. sun_pci_fd_out_byte(port, data, DOR);
  479. sun_pci_fd_out_byte(port, 0x07, FIFO);
  480. sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
  481. do {
  482. udelay(100);
  483. status = sun_pci_fd_sensei(port);
  484. } while (((status & 0xc0) == 0x80) && --timeout);
  485. if (!timeout)
  486. ready = 0;
  487. else
  488. ready = (status & 0x10) ? 0 : 1;
  489. sun_pci_fd_reset(port);
  490. return ready;
  491. }
  492. #undef FIFO
  493. #undef MSR
  494. #undef DOR
  495. #endif /* CONFIG_PCI */
  496. #ifdef CONFIG_PCI
  497. static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
  498. {
  499. if (!strcmp(edev->prom_name, "fdthree"))
  500. return 1;
  501. if (!strcmp(edev->prom_name, "floppy")) {
  502. char compat[16];
  503. prom_getstring(edev->prom_node,
  504.        "compatible",
  505.        compat, sizeof(compat));
  506. compat[15] = '';
  507. if (!strcmp(compat, "fdthree"))
  508. return 1;
  509. }
  510. return 0;
  511. }
  512. #endif
  513. #ifdef CONFIG_PCI
  514. #undef ISA_FLOPPY_WORKS
  515. #ifdef ISA_FLOPPY_WORKS
  516. static unsigned long __init isa_floppy_init(void)
  517. {
  518. struct isa_bridge *isa_br;
  519. struct isa_device *isa_dev = NULL;
  520. for_each_isa(isa_br) {
  521. for_each_isadev(isa_dev, isa_br) {
  522. if (!strcmp(isa_dev->prom_name, "dma")) {
  523. struct isa_device *child = isa_dev->child;
  524. while (child) {
  525. if (!strcmp(child->prom_name, "floppy")) {
  526. isa_dev = child;
  527. goto isa_done;
  528. }
  529. child = child->next;
  530. }
  531. }
  532. }
  533. }
  534. isa_done:
  535. if (!isa_dev)
  536. return 0;
  537. /* We could use DMA on devices behind the ISA bridge, but...
  538.  *
  539.  * There is a slight problem.  Normally on x86 kit the x86 processor
  540.  * delays I/O port instructions when the ISA bus "dma in progress"
  541.  * signal is active.  Well, sparc64 systems do not monitor this
  542.  * signal thus we would need to block all I/O port accesses in software
  543.  * when a dma transfer is active for some device.
  544.  */
  545. sun_fdc = (struct sun_flpy_controller *)isa_dev->resource.start;
  546. FLOPPY_IRQ = isa_dev->irq;
  547. sun_fdops.fd_inb = sun_pci_fd_inb;
  548. sun_fdops.fd_outb = sun_pci_fd_outb;
  549. can_use_virtual_dma = use_virtual_dma = 1;
  550. sun_fdops.fd_enable_dma = sun_fd_enable_dma;
  551. sun_fdops.fd_disable_dma = sun_fd_disable_dma;
  552. sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
  553. sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
  554. sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
  555. sun_fdops.get_dma_residue = sun_get_dma_residue;
  556. sun_fdops.fd_enable_irq = sun_fd_enable_irq;
  557. sun_fdops.fd_disable_irq = sun_fd_disable_irq;
  558. sun_fdops.fd_request_irq = sun_fd_request_irq;
  559. sun_fdops.fd_free_irq = sun_fd_free_irq;
  560. /* Floppy eject is manual.   Actually, could determine this
  561.  * via presence of 'manual' property in OBP node.
  562.  */
  563. sun_fdops.fd_eject = sun_pci_fd_eject;
  564.         fdc_status = (unsigned long) &sun_fdc->status_82077;
  565. FLOPPY_MOTOR_MASK = 0xf0;
  566. allowed_drive_mask = 0;
  567. sun_floppy_types[0] = 0;
  568. sun_floppy_types[1] = 4;
  569. sun_pci_broken_drive = 1;
  570. sun_fdops.fd_outb = sun_pci_fd_broken_outb;
  571. return sun_floppy_types[0];
  572. }
  573. #endif /* ISA_FLOPPY_WORKS */
  574. #endif
  575. static unsigned long __init sun_floppy_init(void)
  576. {
  577. char state[128];
  578. struct sbus_bus *bus;
  579. struct sbus_dev *sdev = NULL;
  580. static int initialized = 0;
  581. if (initialized)
  582. return sun_floppy_types[0];
  583. initialized = 1;
  584. for_all_sbusdev (sdev, bus) {
  585. if (!strcmp(sdev->prom_name, "SUNW,fdtwo")) 
  586. break;
  587. }
  588. if(sdev) {
  589. floppy_sdev = sdev;
  590. FLOPPY_IRQ = sdev->irqs[0];
  591. } else {
  592. #ifdef CONFIG_PCI
  593. struct linux_ebus *ebus;
  594. struct linux_ebus_device *edev = 0;
  595. unsigned long config = 0;
  596. unsigned long auxio_reg;
  597. for_each_ebus(ebus) {
  598. for_each_ebusdev(edev, ebus) {
  599. if (ebus_fdthree_p(edev))
  600. goto ebus_done;
  601. }
  602. }
  603. ebus_done:
  604. if (!edev) {
  605. #ifdef ISA_FLOPPY_WORKS
  606. return isa_floppy_init();
  607. #else
  608. return 0;
  609. #endif
  610. }
  611. prom_getproperty(edev->prom_node, "status",
  612.  state, sizeof(state));
  613. if(!strncmp(state, "disabled", 8))
  614. return 0;
  615. sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start;
  616. FLOPPY_IRQ = edev->irqs[0];
  617. /* Make sure the high density bit is set, some systems
  618.  * (most notably Ultra5/Ultra10) come up with it clear.
  619.  */
  620. auxio_reg = edev->resource[2].start;
  621. writel(readl(auxio_reg)|0x2, auxio_reg);
  622. sun_pci_ebus_dev = ebus->self;
  623. sun_pci_fd_ebus_dma = (struct linux_ebus_dma *)
  624. edev->resource[1].start;
  625. sun_pci_fd_reset_dma();
  626. sun_fdops.fd_inb = sun_pci_fd_inb;
  627. sun_fdops.fd_outb = sun_pci_fd_outb;
  628. can_use_virtual_dma = use_virtual_dma = 0;
  629. sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
  630. sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
  631. sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
  632. sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
  633. sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
  634. sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
  635. sun_fdops.fd_enable_irq = sun_pci_fd_enable_irq;
  636. sun_fdops.fd_disable_irq = sun_pci_fd_disable_irq;
  637. sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
  638. sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
  639. sun_fdops.fd_eject = sun_pci_fd_eject;
  640.          fdc_status = (unsigned long) &sun_fdc->status_82077;
  641. FLOPPY_MOTOR_MASK = 0xf0;
  642. /*
  643.  * XXX: Find out on which machines this is really needed.
  644.  */
  645. if (1) {
  646. sun_pci_broken_drive = 1;
  647. sun_fdops.fd_outb = sun_pci_fd_broken_outb;
  648. }
  649. allowed_drive_mask = 0;
  650. if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
  651. sun_floppy_types[0] = 4;
  652. if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
  653. sun_floppy_types[1] = 4;
  654. /*
  655.  * Find NS87303 SuperIO config registers (through ecpp).
  656.  */
  657. for_each_ebus(ebus) {
  658. for_each_ebusdev(edev, ebus) {
  659. if (!strcmp(edev->prom_name, "ecpp")) {
  660. config = edev->resource[1].start;
  661. goto config_done;
  662. }
  663. }
  664. }
  665. config_done:
  666. /*
  667.  * Sanity check, is this really the NS87303?
  668.  */
  669. switch (config & 0x3ff) {
  670. case 0x02e:
  671. case 0x15c:
  672. case 0x26e:
  673. case 0x398:
  674. break;
  675. default:
  676. config = 0;
  677. }
  678. if (!config)
  679. return sun_floppy_types[0];
  680. /* Enable PC-AT mode. */
  681. ns87303_modify(config, ASC, 0, 0xc0);
  682. #ifdef PCI_FDC_SWAP_DRIVES
  683. /*
  684.  * If only Floppy 1 is present, swap drives.
  685.  */
  686. if (!sun_floppy_types[0] && sun_floppy_types[1]) {
  687. /*
  688.  * Set the drive exchange bit in FCR on NS87303,
  689.  * make shure other bits are sane before doing so.
  690.  */
  691. ns87303_modify(config, FER, FER_EDM, 0);
  692. ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
  693. ns87303_modify(config, FCR, 0, FCR_LDE);
  694. config = sun_floppy_types[0];
  695. sun_floppy_types[0] = sun_floppy_types[1];
  696. sun_floppy_types[1] = config;
  697. if (sun_pci_broken_drive != -1) {
  698. sun_pci_broken_drive = 1 - sun_pci_broken_drive;
  699. sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
  700. }
  701. }
  702. #endif /* PCI_FDC_SWAP_DRIVES */
  703. return sun_floppy_types[0];
  704. #else
  705. return 0;
  706. #endif
  707. }
  708. prom_getproperty(sdev->prom_node, "status", state, sizeof(state));
  709. if(!strncmp(state, "disabled", 8))
  710. return 0;
  711. /*
  712.  * We cannot do sbus_ioremap here: it does request_region,
  713.  * which the generic floppy driver tries to do once again.
  714.  * But we must use the sdev resource values as they have
  715.  * had parent ranges applied.
  716.  */
  717. sun_fdc = (struct sun_flpy_controller *)
  718. (sdev->resource[0].start +
  719.  ((sdev->resource[0].flags & 0x1ffUL) << 32UL));
  720. /* Last minute sanity check... */
  721. if(sbus_readb(&sun_fdc->status1_82077) == 0xff) {
  722. sun_fdc = (struct sun_flpy_controller *)-1;
  723. return 0;
  724. }
  725.         sun_fdops.fd_inb = sun_82077_fd_inb;
  726.         sun_fdops.fd_outb = sun_82077_fd_outb;
  727. can_use_virtual_dma = use_virtual_dma = 1;
  728. sun_fdops.fd_enable_dma = sun_fd_enable_dma;
  729. sun_fdops.fd_disable_dma = sun_fd_disable_dma;
  730. sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
  731. sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
  732. sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
  733. sun_fdops.get_dma_residue = sun_get_dma_residue;
  734. sun_fdops.fd_enable_irq = sun_fd_enable_irq;
  735. sun_fdops.fd_disable_irq = sun_fd_disable_irq;
  736. sun_fdops.fd_request_irq = sun_fd_request_irq;
  737. sun_fdops.fd_free_irq = sun_fd_free_irq;
  738. sun_fdops.fd_eject = sun_fd_eject;
  739.         fdc_status = (unsigned long) &sun_fdc->status_82077;
  740. /* Success... */
  741. allowed_drive_mask = 0x01;
  742. sun_floppy_types[0] = 4;
  743. sun_floppy_types[1] = 0;
  744. return sun_floppy_types[0];
  745. }
  746. #define EXTRA_FLOPPY_PARAMS
  747. #endif /* !(__ASM_SPARC64_FLOPPY_H) */