home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / riscbsd / sources / patches / netbsd / atapi_patc / atapi.patch
Encoding:
Text File  |  1996-06-14  |  147.5 KB  |  5,446 lines

  1. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/arm32/autoconf.c sys/arch/arm32/arm32/autoconf.c
  2. *** sys/arch/arm32.orig/arm32/autoconf.c    Wed Jun 12 20:37:59 1996
  3. --- sys/arch/arm32/arm32/autoconf.c    Thu Jun 13 02:56:50 1996
  4. ***************
  5. *** 59,64 ****
  6. --- 59,65 ----
  7.   #include "rd.h"
  8.   #include "sd.h"
  9.   #include "cd.h"
  10. + #include "acd.h"
  11.   #include "podulebus.h"
  12.   
  13.   extern dev_t rootdev;
  14. ***************
  15. *** 92,97 ****
  16. --- 93,101 ----
  17.   #endif
  18.   #if NSD > 0
  19.       { "sd", 0x18 },
  20. + #endif
  21. + #if NCD > 0
  22. +     { "acd", 0x14 },
  23.   #endif
  24.   #if NCD > 0
  25.       { "cd", 0x1a },
  26. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/arm32/autoconf.c.orig sys/arch/arm32/arm32/autoconf.c.orig
  27. *** sys/arch/arm32.orig/arm32/autoconf.c.orig    Thu Jan  1 01:00:00 1970
  28. --- sys/arch/arm32/arm32/autoconf.c.orig    Wed Jun 12 20:37:59 1996
  29. ***************
  30. *** 0 ****
  31. --- 1,295 ----
  32. + /* $NetBSD: autoconf.c,v 1.7 1996/06/12 19:42:23 mark Exp $ */
  33. + /*
  34. +  * Copyright (c) 1994,1995 Mark Brinicombe.
  35. +  * Copyright (c) 1994 Brini.
  36. +  * All rights reserved.
  37. +  *
  38. +  * Redistribution and use in source and binary forms, with or without
  39. +  * modification, are permitted provided that the following conditions
  40. +  * are met:
  41. +  * 1. Redistributions of source code must retain the above copyright
  42. +  *    notice, this list of conditions and the following disclaimer.
  43. +  * 2. Redistributions in binary form must reproduce the above copyright
  44. +  *    notice, this list of conditions and the following disclaimer in the
  45. +  *    documentation and/or other materials provided with the distribution.
  46. +  * 3. All advertising materials mentioning features or use of this software
  47. +  *    must display the following acknowledgement:
  48. +  *    This product includes software developed by Mark Brinicombe for
  49. +  *      the NetBSD project.
  50. +  * 4. The name of the company nor the name of the author may be used to
  51. +  *    endorse or promote products derived from this software without specific
  52. +  *    prior written permission.
  53. +  *
  54. +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  55. +  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  56. +  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  57. +  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  58. +  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59. +  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  60. +  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  61. +  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  62. +  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  63. +  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  64. +  * SUCH DAMAGE.
  65. +  *
  66. +  * RiscBSD kernel project
  67. +  *
  68. +  * autoconf.c
  69. +  *
  70. +  * Autoconfiguration functions
  71. +  *
  72. +  * Created      : 08/10/94
  73. +  */
  74. + #include <sys/param.h>
  75. + #include <sys/systm.h>
  76. + #include <sys/reboot.h>
  77. + #include <sys/disklabel.h>
  78. + #include <sys/device.h>
  79. + #include <sys/conf.h>
  80. + #include <sys/kernel.h>
  81. + #include <sys/malloc.h>
  82. + #include <machine/irqhandler.h>
  83. + #include <machine/bootconfig.h>
  84. + #include "wdc.h"
  85. + #include "fdc.h"
  86. + #include "rd.h"
  87. + #include "sd.h"
  88. + #include "cd.h"
  89. + #include "podulebus.h"
  90. + extern dev_t rootdev;
  91. + extern dev_t swapdev;
  92. + extern dev_t dumpdev;
  93. + extern dev_t argdev;
  94. + extern struct swdevt swdevt[];
  95. + extern char *boot_args;
  96. + extern int pmap_debug_level;
  97. + char *    strstr    __P((char */*s1*/, char */*s2*/));
  98. + long    strtoul __P((const char *, char **, int));
  99. + void    dumpconf __P(());
  100. + /* Table major numbers for the device names, NULL terminated */
  101. + struct {
  102. +     char *name;
  103. +     dev_t dev;
  104. + } rootdevices[] = {
  105. + #if NWDC > 0
  106. +     { "wd", 0x10 },
  107. + #endif
  108. + #if NFDC > 0
  109. +     { "fd", 0x11 },
  110. + #endif
  111. + #if NRD > 0
  112. +     { "rd", 0x12 },
  113. + #endif
  114. + #if NSD > 0
  115. +     { "sd", 0x18 },
  116. + #endif
  117. + #if NCD > 0
  118. +     { "cd", 0x1a },
  119. + #endif
  120. +     { NULL, 0x00 },
  121. + };
  122. + /* Decode a device name to a major and minor number */
  123. + dev_t
  124. + get_device(name)
  125. +     char *name;
  126. + {
  127. +     int loop;
  128. +     int unit;
  129. +     int part;
  130. +     
  131. +     if (strncmp(name, "/dev/", 5) == 0)
  132. +         name += 5;
  133. +     for (loop = 0; rootdevices[loop].name; ++loop) {
  134. +         if (strncmp(name, rootdevices[loop].name,
  135. +             strlen(rootdevices[loop].name)) == 0) {
  136. +             name += strlen(rootdevices[loop].name);
  137. +             if (name[0] >= '0' && name[0] <= '9')
  138. +                 unit = name[0] - '0';
  139. +             else if (name[0] == 0 || name[0] == ' ')
  140. +                 unit = 0;
  141. +             else
  142. +                 unit = -1;
  143. +             if (name[1] >= 'a' && name[1] <= 'z')
  144. +                 part = name[1] - 'a';
  145. +             else if (name[1] == 0 || name[1] == ' ')
  146. +                 part = 0;
  147. +             else
  148. +                 part = -1;
  149. +             if (unit < 0 || unit > 9)
  150. +                 return(NODEV);
  151. +             if (part < 0 || part > MAXPARTITIONS)
  152. +                 return(NODEV);
  153. +             return(makedev(rootdevices[loop].dev,
  154. +                 unit * MAXPARTITIONS + part));
  155. +         }
  156. +     } 
  157. +     return(NODEV);  
  158. + }
  159. + /* Set the rootdev variable from the root specifier in the boot args */
  160. + void
  161. + set_root_device()
  162. + {
  163. +     char *ptr;
  164. +             
  165. +     if (boot_args) {
  166. +         ptr = strstr(boot_args, "root=");
  167. +         if (ptr) {
  168. +             ptr += 5;
  169. +             rootdev = get_device(ptr);
  170. + #ifdef DEBUG              
  171. +             if (pmap_debug_level >= 0)
  172. +                 printf("rootdev = %08x\n", rootdev);
  173. + #endif
  174. +         }
  175. +     }
  176. +     if (rootdev == NODEV)
  177. +         panic("No root device specified in boot config\n");
  178. + }
  179. + /* Set the swap devices from the swap specifiers in the boot ars */
  180. + void
  181. + set_swap_device()
  182. + {
  183. +     char *ptr;
  184. +     int nswap = 0;
  185. +             
  186. +     if (boot_args) {
  187. +         ptr = boot_args;
  188. +         do {
  189. +             ptr = strstr(ptr, "swap=");
  190. +             if (ptr) {
  191. +                 ptr += 5;
  192. +                 swdevt[nswap].sw_dev = get_device(ptr);
  193. +                 /*
  194. +                  * Remember the first swap device
  195. +                  */
  196. +                 if (nswap == 0)
  197. +                     swapdev = get_device(ptr);
  198. +                 ++nswap;
  199. +             }
  200. +         } while (ptr);
  201. +     }
  202. + }
  203. + /*
  204. +  * Configure swap space and related parameters.
  205. +  */
  206. + void
  207. + swapconf()
  208. + {
  209. +     register struct swdevt *swp;
  210. +     register int nblks;
  211. +     int swapsize = -1;
  212. +     int maj;
  213. +     int s;        /* The spl stuff was here for debugging reaons */
  214. +     /*
  215. +      * Loop round all the defined swap device configuring them.
  216. +      */
  217. +     for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
  218. +         maj = major(swp->sw_dev);
  219. +         if (maj > nblkdev)
  220. +             break;
  221. +         if (bdevsw[maj].d_psize) {
  222. +             s = spltty();
  223. +             printf("swap dev %04x ", swp->sw_dev);
  224. +             (void)splx(s);
  225. +             if (swapsize == -1)
  226. +                 nblks = (*bdevsw[maj].d_psize)(swp->sw_dev);
  227. +                 else
  228. +                 nblks = swapsize;
  229. +             s = spltty();
  230. +             if (nblks == -1)
  231. +                 printf("-> device not configured for swap\n");
  232. +             else
  233. +                 printf("-> %d bytes\n", nblks*DEV_BSIZE);
  234. +             (void)splx(s);
  235. +             if (nblks != -1 &&
  236. +                 (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
  237. +                 swp->sw_nblks = nblks;
  238. +             swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
  239. +         }
  240. +     }
  241. + }
  242. + /* Set up the root and swap device numbers, configure the swap space and dump space */
  243. + void
  244. + set_boot_devs()
  245. + {
  246. +     set_root_device();
  247. +     set_swap_device();
  248. +     if (swapdev == NODEV && minor(rootdev) < (MAXPARTITIONS - 2))
  249. +         swapdev = makedev(major(rootdev), minor(rootdev) + 1);
  250. +     dumpdev = swapdev;
  251. +     argdev = swapdev;
  252. +     swdevt[0].sw_dev = swapdev;
  253. +     swapconf();
  254. +     dumpconf();
  255. + }
  256. + /*
  257. +  * void configure()
  258. +  *
  259. +  * Configure all the root devices
  260. +  * The root devices are expected to configure their own children
  261. +  */
  262. + void
  263. + configure()
  264. + {
  265. + /*
  266. +  * Configure all the roots.
  267. +  * We have to have a mainbus
  268. +  */
  269. +     config_rootfound("mainbus", NULL);
  270. + #if NPODULEBUS > 0
  271. +     config_rootfound("podulebus", NULL);
  272. + #endif
  273. + /* Debugging information */
  274. +     printf("ipl_bio=%08x ipl_net=%08x ipl_tty=%08x ipl_clock=%08x ipl_imp=%08x ipl_none=%08x\n",
  275. +         irqmasks[IPL_BIO], irqmasks[IPL_NET], irqmasks[IPL_TTY],
  276. +         irqmasks[IPL_CLOCK], irqmasks[IPL_IMP], irqmasks[IPL_NONE]);
  277. + /* Time to start taking interrupts so lets open the flood gates .... */
  278. +          
  279. +     (void)spl0();
  280. + }
  281. + /* End of autoconf.c */
  282. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/arm32/conf.c sys/arch/arm32/arm32/conf.c
  283. *** sys/arch/arm32.orig/arm32/conf.c    Mon Jun  3 22:33:15 1996
  284. --- sys/arch/arm32/arm32/conf.c    Thu Jun 13 02:56:51 1996
  285. ***************
  286. *** 77,82 ****
  287. --- 77,84 ----
  288.   bdev_decl(vnd);
  289.   #include "ccd.h"
  290.   bdev_decl(ccd);
  291. + #include "acd.h"
  292. + bdev_decl(acd);
  293.   
  294.   /* Block devices */
  295.   
  296. ***************
  297. *** 101,107 ****
  298.       bdev_disk_init(NFDC, fd),    /* 17: floppy diskette */
  299.       bdev_disk_init(NRD, rd),    /* 18: ramdisk */
  300.       bdev_disk_init(NVND,vnd),    /* 19: vnode disk driver */
  301. !     bdev_lkm_dummy(),        /* 20: */
  302.        bdev_disk_init(NCCD,ccd),    /* 21: concatenated disk driver */
  303.       bdev_lkm_dummy(),        /* 22: */
  304.       bdev_lkm_dummy(),        /* 23: */
  305. --- 103,109 ----
  306.       bdev_disk_init(NFDC, fd),    /* 17: floppy diskette */
  307.       bdev_disk_init(NRD, rd),    /* 18: ramdisk */
  308.       bdev_disk_init(NVND,vnd),    /* 19: vnode disk driver */
  309. !     bdev_disk_init(NACD,acd),    /* 20: ATAPI CD-ROM */
  310.        bdev_disk_init(NCCD,ccd),    /* 21: concatenated disk driver */
  311.       bdev_lkm_dummy(),        /* 22: */
  312.       bdev_lkm_dummy(),        /* 23: */
  313. ***************
  314. *** 244,249 ****
  315. --- 246,252 ----
  316.   cdev_decl(tun);
  317.   cdev_decl(vnd);
  318.   cdev_decl(ccd);
  319. + cdev_decl(acd);
  320.   #include "quadmouse.h"
  321.   cdev_decl(quadmouse);
  322.   #include "pms.h"
  323. ***************
  324. *** 284,290 ****
  325.       cdev_disk_init(NFDC, fd),       /* 17: floppy diskette */
  326.       cdev_disk_init(NRD, rd),        /* 18: ram disk driver */
  327.       cdev_disk_init(NVND,vnd),       /* 19: vnode disk driver */
  328. !     cdev_lkm_dummy(),        /* 20: */
  329.        cdev_disk_init(NCCD,ccd),    /* 21: concatenated disk driver */
  330.       cdev_lkm_dummy(),        /* 22: */
  331.       cdev_lkm_dummy(),        /* 23: */
  332. --- 287,293 ----
  333.       cdev_disk_init(NFDC, fd),       /* 17: floppy diskette */
  334.       cdev_disk_init(NRD, rd),        /* 18: ram disk driver */
  335.       cdev_disk_init(NVND,vnd),       /* 19: vnode disk driver */
  336. !     cdev_disk_init(NACD,acd),    /* 20: ATAPI CD-ROM */
  337.        cdev_disk_init(NCCD,ccd),    /* 21: concatenated disk driver */
  338.       cdev_lkm_dummy(),        /* 22: */
  339.       cdev_lkm_dummy(),        /* 23: */
  340. ***************
  341. *** 359,365 ****
  342.       /* 17 */        17,
  343.       /* 18 */        18,
  344.       /* 19 */        19,
  345. !     /* 20 */        NODEV,
  346.       /* 21 */        21,
  347.       /* 22 */        NODEV,
  348.       /* 23 */        NODEV,
  349. --- 362,368 ----
  350.       /* 17 */        17,
  351.       /* 18 */        18,
  352.       /* 19 */        19,
  353. !     /* 20 */        20,
  354.       /* 21 */        21,
  355.       /* 22 */        NODEV,
  356.       /* 23 */        NODEV,
  357. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/arm32/conf.c.orig sys/arch/arm32/arm32/conf.c.orig
  358. *** sys/arch/arm32.orig/arm32/conf.c.orig    Thu Jan  1 01:00:00 1970
  359. --- sys/arch/arm32/arm32/conf.c.orig    Mon Jun  3 22:33:15 1996
  360. ***************
  361. *** 0 ****
  362. --- 1,430 ----
  363. + /* $NetBSD: conf.c,v 1.8 1996/06/03 21:36:14 mark Exp $ */
  364. + /*
  365. +  * Copyright (c) 1994 Mark Brinicombe.
  366. +  * Copyright (c) 1994 Brini.
  367. +  * All rights reserved.
  368. +  *
  369. +  * Redistribution and use in source and binary forms, with or without
  370. +  * modification, are permitted provided that the following conditions
  371. +  * are met:
  372. +  * 1. Redistributions of source code must retain the above copyright
  373. +  *    notice, this list of conditions and the following disclaimer.
  374. +  * 2. Redistributions in binary form must reproduce the above copyright
  375. +  *    notice, this list of conditions and the following disclaimer in the
  376. +  *    documentation and/or other materials provided with the distribution.
  377. +  * 3. All advertising materials mentioning features or use of this software
  378. +  *    must display the following acknowledgement:
  379. +  *    This product includes software developed by Mark Brinicombe.
  380. +  * 4. The name of the company nor the name of the author may be used to
  381. +  *    endorse or promote products derived from this software without specific
  382. +  *    prior written permission.
  383. +  *
  384. +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  385. +  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  386. +  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  387. +  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  388. +  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  389. +  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  390. +  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  391. +  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  392. +  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  393. +  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  394. +  * SUCH DAMAGE.
  395. +  *
  396. +  * RiscBSD kernel project
  397. +  *
  398. +  * conf.c
  399. +  *
  400. +  * Character and Block Device configuration
  401. +  * Console configuration
  402. +  *
  403. +  * Defines the structures cdevsw and constab
  404. +  *
  405. +  * Created      : 17/09/94
  406. +  */
  407. +  
  408. + #include <sys/param.h>
  409. + #include <sys/systm.h>
  410. + #include <sys/buf.h>
  411. + #include <sys/ioctl.h>
  412. + #include <sys/tty.h>
  413. + #include <sys/conf.h>
  414. + #include <sys/vnode.h>
  415. + int     ttselect        __P((dev_t, int, struct proc *));
  416. + #ifndef LKM
  417. + #define lkmenodev       enodev
  418. + #else
  419. + int     lkmenodev();
  420. + #endif
  421. + #include "wdc.h"
  422. + bdev_decl(wd);
  423. + bdev_decl(sw);
  424. + #include "fdc.h"
  425. + bdev_decl(fd);
  426. + #include "rd.h"
  427. + bdev_decl(rd);
  428. + #include "sd.h"
  429. + bdev_decl(sd);
  430. + #include "st.h"
  431. + bdev_decl(st);
  432. + #include "cd.h"
  433. + bdev_decl(cd);
  434. + #include "vnd.h"
  435. + bdev_decl(vnd);
  436. + #include "ccd.h"
  437. + bdev_decl(ccd);
  438. + /* Block devices */
  439. + struct bdevsw bdevsw[] = {
  440. +     bdev_lkm_dummy(),        /*  0: */
  441. +     bdev_swap_init(1, sw),        /*  1: swap pseudo-device */
  442. +     bdev_lkm_dummy(),        /*  2: */
  443. +     bdev_lkm_dummy(),        /*  3: */
  444. +     bdev_lkm_dummy(),        /*  4: */
  445. +     bdev_lkm_dummy(),        /*  5: */
  446. +     bdev_lkm_dummy(),        /*  6: */
  447. +     bdev_lkm_dummy(),        /*  7: */
  448. +     bdev_lkm_dummy(),        /*  8: */
  449. +     bdev_lkm_dummy(),        /*  9: */
  450. +     bdev_lkm_dummy(),        /* 10: */
  451. +     bdev_lkm_dummy(),        /* 11: */
  452. +     bdev_lkm_dummy(),        /* 12: */
  453. +     bdev_lkm_dummy(),        /* 13: */
  454. +     bdev_lkm_dummy(),        /* 14: */
  455. +     bdev_lkm_dummy(),        /* 15: */
  456. +     bdev_disk_init(NWDC, wd),    /* 16: Internal IDE disk */
  457. +     bdev_disk_init(NFDC, fd),    /* 17: floppy diskette */
  458. +     bdev_disk_init(NRD, rd),    /* 18: ramdisk */
  459. +     bdev_disk_init(NVND,vnd),    /* 19: vnode disk driver */
  460. +     bdev_lkm_dummy(),        /* 20: */
  461. +      bdev_disk_init(NCCD,ccd),    /* 21: concatenated disk driver */
  462. +     bdev_lkm_dummy(),        /* 22: */
  463. +     bdev_lkm_dummy(),        /* 23: */
  464. +     bdev_disk_init(NSD,sd),        /* 24: SCSI disk */
  465. +     bdev_tape_init(NST,st),        /* 25: SCSI tape */
  466. +     bdev_disk_init(NCD,cd),        /* 26: SCSI cdrom */
  467. +     bdev_lkm_dummy(),        /* 27: */
  468. +     bdev_lkm_dummy(),        /* 28: */
  469. +     bdev_lkm_dummy(),        /* 29: */
  470. +     bdev_lkm_dummy(),        /* 30: */
  471. +     bdev_lkm_dummy(),        /* 31: */
  472. +     bdev_lkm_dummy(),        /* 32: */
  473. +     bdev_lkm_dummy(),        /* 33: */
  474. +     bdev_lkm_dummy(),        /* 34: */
  475. +     bdev_lkm_dummy(),        /* 35: */
  476. +     bdev_lkm_dummy(),        /* 36: */
  477. +     bdev_lkm_dummy(),        /* 37: */
  478. +     bdev_lkm_dummy(),        /* 38: */
  479. +     bdev_lkm_dummy(),        /* 39: */
  480. +     bdev_lkm_dummy(),        /* 40: */
  481. +     bdev_lkm_dummy(),        /* 41: */
  482. +     bdev_lkm_dummy(),        /* 42: */
  483. +     bdev_lkm_dummy(),        /* 43: */
  484. +   };
  485. + int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
  486. + /* Character device declarations */
  487. + /* open, close, read, write, ioctl, tty, mmap */
  488. + #define cdev_physcon_init(c,n) { \
  489. +     dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
  490. +     dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \
  491. +     dev_init(c,n,tty), ttselect, dev_init(c,n,mmap), 0 }
  492. + /* open, close, write, ioctl */
  493. + #define cdev_lpt_init(c,n) { \
  494. +     dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
  495. +     dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
  496. +     0, seltrue, (dev_type_mmap((*))) enodev, 0 }
  497. + /* open, close, write, ioctl */
  498. + #define cdev_beep_init(c,n) { \
  499. +     dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
  500. +     (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
  501. +     (dev_type_stop((*))) enodev, \
  502. +     0, seltrue, (dev_type_mmap((*))) enodev, 0 }
  503. + /* open, close, write, ioctl */
  504. + #define cdev_kbd_init(c,n) { \
  505. +     dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
  506. +     (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
  507. +     (dev_type_stop((*))) enodev, \
  508. +     0, dev_init(c,n,select), (dev_type_mmap((*))) enodev, 0 }
  509. + /* open, close, write, ioctl */
  510. + #define cdev_cpu_init(c,n) { \
  511. +     dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
  512. +     (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
  513. +     (dev_type_stop((*))) enodev, \
  514. +     0, seltrue, (dev_type_mmap((*))) enodev, 0 }
  515. + /* open, close, write, ioctl */
  516. + #define cdev_vidcvid_init(c,n) { \
  517. +     dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
  518. +     (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
  519. +     (dev_type_stop((*))) enodev, \
  520. +     0, seltrue, dev_init(c,n,mmap), 0 }
  521. + /* open, close, write, ioctl */
  522. + #define cdev_uk_init(c,n) { \
  523. +     dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
  524. +     dev_init(c,n,write), dev_init(c,n,ioctl), \
  525. +     (dev_type_stop((*))) enodev, \
  526. +     0, seltrue, (dev_type_mmap((*))) enodev, 0 }
  527. + /* open, close, read, ioctl */
  528. + #define cdev_ss_init(c,n) { \
  529. +     dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
  530. +     (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
  531. +     (dev_type_stop((*))) enodev, 0, seltrue, \
  532. +     (dev_type_mmap((*))) enodev }
  533. + /* open, close, write, ioctl */
  534. + #define cdev_iic_init(c,n) { \
  535. +     dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
  536. +     dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
  537. +     0, seltrue, (dev_type_mmap((*))) enodev, 0 }
  538. + /* open, close, write, ioctl */
  539. + #define cdev_rtc_init(c,n) { \
  540. +     dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
  541. +     dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
  542. +     0, seltrue, (dev_type_mmap((*))) enodev, 0 }
  543. + cdev_decl(cn);
  544. + cdev_decl(ctty);
  545. + #include "vt.h"                                 
  546. + cdev_decl(physcon);
  547. + cdev_decl(vidcvideo);
  548. + #define mmread  mmrw
  549. + #define mmwrite mmrw
  550. + cdev_decl(mm);
  551. + cdev_decl(wd);
  552. + cdev_decl(sw);
  553. + #include "pty.h"
  554. + #define ptstty          ptytty
  555. + #define ptsioctl        ptyioctl
  556. + cdev_decl(pts);
  557. + #define ptctty          ptytty
  558. + #define ptcioctl        ptyioctl
  559. + cdev_decl(ptc);
  560. + cdev_decl(log);
  561. + #include "com.h"
  562. + cdev_decl(com);
  563. + #include "lpt.h"
  564. + cdev_decl(lpt);
  565. + cdev_decl(fd);
  566. + dev_decl(filedesc,open);
  567. + cdev_decl(rd);
  568. + #include "bpfilter.h"
  569. + cdev_decl(bpf);
  570. + cdev_decl(sd);
  571. + cdev_decl(st);
  572. + cdev_decl(cd);
  573. + #include "ch.h"
  574. + cdev_decl(ch);
  575. + #include "uk.h"
  576. + cdev_decl(uk);
  577. + #include "ss.h"
  578. + cdev_decl(ss);
  579. + #ifdef LKM
  580. + #define    NLKM    1
  581. + #else
  582. + #define    NLKM    0
  583. + #endif
  584. + cdev_decl(lkm);
  585. + #include "tun.h"
  586. + cdev_decl(tun);
  587. + cdev_decl(vnd);
  588. + cdev_decl(ccd);
  589. + #include "quadmouse.h"
  590. + cdev_decl(quadmouse);
  591. + #include "pms.h"
  592. + cdev_decl(pms);
  593. + #include "beep.h"
  594. + cdev_decl(beep);
  595. + #include "kbd.h"
  596. + cdev_decl(kbd);
  597. + #include "audio.h"
  598. + cdev_decl(audio);
  599. + #include "cpu.h"
  600. + cdev_decl(cpu);
  601. + #include "iic.h"
  602. + cdev_decl(iic);
  603. + #include "rtc.h"
  604. + cdev_decl(rtc);
  605. + /* Character devices */
  606. + struct cdevsw cdevsw[] = {
  607. +     cdev_mm_init(1, mm),            /*  0: /dev/{null,mem,kmem,...} */
  608. +     cdev_swap_init(1, sw),          /*  1: /dev/drum (swap pseudo-device) */
  609. +     cdev_cn_init(1, cn),            /*  2: virtual console */
  610. +     cdev_ctty_init(1,ctty),         /*  3: controlling terminal */
  611. +     cdev_physcon_init(NVT, physcon),  /*  4: RPC console */
  612. +         cdev_log_init(1,log),           /*  5: /dev/klog */
  613. +     cdev_ptc_init(NPTY,ptc),        /*  6: pseudo-tty master */
  614. +     cdev_tty_init(NPTY,pts),        /*  7: pseudo-tty slave */
  615. +     cdev_lpt_init(NLPT,lpt),        /*  8: parallel printer */
  616. +     cdev_mouse_init(NQUADMOUSE,quadmouse),       /* 9: quadmouse driver */
  617. +     cdev_beep_init(NBEEP,beep),    /* 10: simple beep device */
  618. +     cdev_kbd_init(NKBD,kbd),    /* 11: kbd device */
  619. +     cdev_tty_init(NCOM,com),        /* 12: serial port */
  620. +     cdev_lkm_dummy(),        /* 13: */
  621. +     cdev_lkm_dummy(),        /* 14: */
  622. +     cdev_lkm_dummy(),        /* 15: */
  623. +     cdev_disk_init(NWDC, wd),       /* 16: ST506/ESDI/IDE disk */
  624. +     cdev_disk_init(NFDC, fd),       /* 17: floppy diskette */
  625. +     cdev_disk_init(NRD, rd),        /* 18: ram disk driver */
  626. +     cdev_disk_init(NVND,vnd),       /* 19: vnode disk driver */
  627. +     cdev_lkm_dummy(),        /* 20: */
  628. +      cdev_disk_init(NCCD,ccd),    /* 21: concatenated disk driver */
  629. +     cdev_lkm_dummy(),        /* 22: */
  630. +     cdev_lkm_dummy(),        /* 23: */
  631. +     cdev_disk_init(NSD,sd),            /* 24: SCSI disk */
  632. +     cdev_tape_init(NST,st),           /* 25: SCSI tape */
  633. +     cdev_disk_init(NCD,cd),            /* 26: SCSI CD-ROM */
  634. +     cdev_ch_init(NCH,ch),         /* 27: SCSI autochanger */
  635. +     cdev_ch_init(NUK,uk),         /* 28: SCSI unknown */
  636. +     cdev_ss_init(NSS,ss),         /* 29: SCSI scanner */
  637. +     cdev_lkm_dummy(),        /* 30: */
  638. +     cdev_lkm_dummy(),        /* 31: */
  639. +     cdev_bpftun_init(NBPFILTER,bpf),/* 32: Berkeley packet filter */
  640. +         cdev_bpftun_init(NTUN,tun),     /* 33: network tunnel */
  641. +         cdev_fd_init(1,filedesc),       /* 34: file descriptor pseudo-device */
  642. +     cdev_lkm_init(NLKM,lkm),        /* 35: loadable module driver */
  643. +     cdev_audio_init(NAUDIO,audio),    /* 36: generic audio I/O */
  644. +     cdev_vidcvid_init(1,vidcvideo),    /* 37: vidcvideo device */
  645. +     cdev_cpu_init(NCPU,cpu),    /* 38: cpu device */
  646. +     cdev_lkm_dummy(),        /* 39: */
  647. +     cdev_mouse_init(NPMS,pms),      /* 40: PS2 mouse driver */
  648. +     cdev_lkm_dummy(),        /* 41: */
  649. +     cdev_iic_init(NIIC, iic),    /* 42: IIC bus driver */
  650. +     cdev_rtc_init(NRTC, rtc),    /* 43: RTC driver */
  651. + };
  652. + int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
  653. + int mem_no = 0;     /* major device number of memory special file */
  654. + /*
  655. +  * Returns true if dev is /dev/mem or /dev/kmem.
  656. +  */
  657. + int
  658. + iskmemdev(dev)
  659. +     dev_t dev;
  660. + {
  661. +     return (major(dev) == mem_no && minor(dev) < 2);
  662. + }
  663. + /*
  664. +  * Returns true if dev is /dev/zero.
  665. +  */
  666. + int
  667. + iszerodev(dev)
  668. +     dev_t dev;
  669. + {
  670. +     return (major(dev) == mem_no && minor(dev) == 3);
  671. + }
  672. + static int chrtoblktbl[] = {
  673. + /* XXXX This needs to be dynamic for LKMs. */
  674. +     /*VCHR*/        /*VBLK*/
  675. +     /*  0 */        NODEV,
  676. +     /*  1 */        1,
  677. +     /*  2 */        NODEV,
  678. +     /*  3 */        NODEV,
  679. +     /*  4 */        NODEV,
  680. +     /*  5 */        NODEV,
  681. +     /*  6 */        NODEV,
  682. +     /*  7 */        NODEV,
  683. +     /*  8 */        NODEV,
  684. +     /*  9 */        NODEV,
  685. +     /* 10 */        NODEV,
  686. +     /* 11 */        NODEV,
  687. +     /* 12 */        NODEV,
  688. +     /* 13 */        NODEV,
  689. +     /* 14 */        NODEV,
  690. +     /* 15 */        NODEV,
  691. +     /* 16 */        16,
  692. +     /* 17 */        17,
  693. +     /* 18 */        18,
  694. +     /* 19 */        19,
  695. +     /* 20 */        NODEV,
  696. +     /* 21 */        21,
  697. +     /* 22 */        NODEV,
  698. +     /* 23 */        NODEV,
  699. +     /* 24 */        24,
  700. +     /* 25 */        25,
  701. +     /* 26 */        26,
  702. +     /* 27 */        NODEV,
  703. +     /* 28 */        NODEV,
  704. +     /* 29 */        NODEV,
  705. +     /* 30 */        NODEV,
  706. +     /* 31 */        NODEV,
  707. +     /* 32 */        NODEV,
  708. +     /* 33 */        NODEV,
  709. +     /* 34 */        NODEV,
  710. +     /* 35 */        NODEV,
  711. +     /* 36 */        NODEV,
  712. +     /* 37 */        NODEV,
  713. +     /* 38 */        NODEV,
  714. +     /* 39 */        NODEV,
  715. +     /* 40 */        NODEV,
  716. +     /* 41 */        NODEV,
  717. +     /* 42 */        NODEV,
  718. +     /* 43 */        NODEV,
  719. + };
  720. + /*
  721. +  * Convert a character device number to a block device number.
  722. +  */
  723. +  
  724. + dev_t
  725. + chrtoblk(dev)
  726. +     dev_t dev;
  727. + {
  728. +     int blkmaj;
  729. +                   
  730. +     if (major(dev) >= nchrdev)
  731. +         return (NODEV);
  732. +     blkmaj = chrtoblktbl[major(dev)];
  733. +     if (blkmaj == NODEV)
  734. +         return (NODEV);
  735. +     return (makedev(blkmaj, minor(dev)));
  736. + }
  737. +                                                                                    
  738. + /*
  739. +  * This entire table could be autoconfig()ed but that would mean that
  740. +  * the kernel's idea of the console would be out of sync with that of
  741. +  * the standalone boot.  I think it best that they both use the same
  742. +  * known algorithm unless we see a pressing need otherwise.
  743. +  */
  744. + #include <dev/cons.h>
  745. + cons_decl(rpcconsole);
  746. + cons_decl(com);   
  747. +        
  748. + struct consdev constab[] = {
  749. + #if (NVT + NRPC > 0)
  750. +     cons_init(rpcconsole),
  751. + #endif
  752. + /*#if (NCOM > 0)
  753. +     cons_init(com),
  754. + #endif*/
  755. +     { 0 },
  756. + };
  757. +                            
  758. + /* End of conf.c */
  759. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/conf/VOYAGER sys/arch/arm32/conf/VOYAGER
  760. *** sys/arch/arm32.orig/conf/VOYAGER    Thu Jun 13 02:08:19 1996
  761. --- sys/arch/arm32/conf/VOYAGER    Thu Jun 13 02:56:51 1996
  762. ***************
  763. *** 124,129 ****
  764. --- 124,132 ----
  765.   wdc0    at mainbus? base 0x002107c0 irq 9
  766.   wd*     at wdc? drive ?
  767.   
  768. + atapibus* at wdc?
  769. + acd* at atapibus? drive?
  770.   # Floppy disk controller
  771.   fdc0    at mainbus? base 0x00210fc0 irq 12 dack 0x00002000
  772.   fd0     at fdc? drive ?
  773. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/conf/VOYAGER.orig sys/arch/arm32/conf/VOYAGER.orig
  774. *** sys/arch/arm32.orig/conf/VOYAGER.orig    Thu Jan  1 01:00:00 1970
  775. --- sys/arch/arm32/conf/VOYAGER.orig    Thu Jun 13 02:08:19 1996
  776. ***************
  777. *** 0 ****
  778. --- 1,201 ----
  779. + #
  780. + #    VOYAGER -- Mark's master development machine
  781. + #
  782. + include    "std.arm32"
  783. + # estimated number of users
  784. + maxusers    32
  785. + # Standard system options
  786. + options        TIMEZONE=0    # time zone to adjust RTC time by
  787. + options        DST=0        # daylight savings time used by RTC
  788. + options        SWAPPAGER    # paging; REQUIRED
  789. + options        VNODEPAGER    # mmap() of files
  790. + options        DEVPAGER    # mmap() of devices
  791. + # CPU options
  792. + options        CPU_ARM6
  793. + options        CPU_LATE_ABORT    # ARM7XX compatibility
  794. + # FPA options
  795. + #options        FPE        # Single precision FPE
  796. + options        ARMFPE        # ARM Ltd FPE
  797. + # File system options
  798. + options        FFS        # UFS
  799. + #options    QUOTA        # UFS quotas
  800. + #options    LFS        # log-structured file system
  801. + options        MFS        # memory file system
  802. + options        CD9660        # ISO 9660 + Rock Ridge file system
  803. + options        MSDOSFS        # MS-DOS file system
  804. + options        FDESC        # /dev/fd
  805. + options        FIFO        # FIFOs; RECOMMENDED
  806. + options        KERNFS        # /kern
  807. + options        NULLFS        # loopback file system
  808. + #options    PORTAL        # portal filesystem (still experimental)
  809. + options        PROCFS        # /proc
  810. + options        UMAPFS        # NULLFS + uid and gid remapping
  811. + options        UNION        # union file system
  812. + # Networking options
  813. + options        NFSCLIENT
  814. + options        NFSSERVER
  815. + options        GATEWAY        # packet forwarding
  816. + options        INET        # IP + ICMP + TCP + UDP
  817. + #options    NS        # XNS
  818. + #options    ISO,TPIP    # OSI
  819. + #options    EON        # OSI tunneling over IP
  820. + #options    CCITT,LLC,HDLC    # X.25
  821. + # Compatibility options
  822. + options        COMPAT_43
  823. + options        COMPAT_10
  824. + options        COMPAT_09
  825. + options         TCP_COMPAT_42   # TCP bug compatibility with 4.2BSD
  826. + # Shared memory options
  827. + options        SYSVMSG        # System V-like message queues
  828. + options        SYSVSEM        # System V-like semaphores
  829. + options        SYSVSHM        # System V-like memory sharing
  830. + options        SHMMAXPGS=1024    # 1024 pages is the default
  831. + # Device options
  832. + options        RAMDISK_HOOKS    # boottime setup of ramdisk
  833. + options        RAMDISK_SIZE=0    # Size in KBytes
  834. + options        PLIP        # Build plip device into lpt driver
  835. + # Development options
  836. + #options    ARM700BUGTRACK    # track the ARM700 swi bug
  837. + options        HYDRA        # Experimental hydra support
  838. + options        MPSUPPORT    # Experimental MP support
  839. + options        DIAGNOSTIC    # internally consistency checks
  840. + options        KTRACE        # system call tracing, a la ktrace(1)
  841. + options        IRQSTATS    # IRQ statistics
  842. + options        POSTMORTEM    # perform postmortem on panic
  843. + #options    ROTTEN_INNARDS    # show the gory bit of the postmortem
  844. + options        KSHELL        # kernel developemnt shell (debug)
  845. + options        LKM        # loadable kernel modules
  846. + #options    DEBUGTERM    # create a debug console
  847. + #options    KGDB        # remote kernel debugging
  848. + options        DDB        # in-kernel debugger
  849. + #makeoptions    DEBUG="-g"    # compile full symbol table
  850. + config        netbsd    swap generic
  851. + options        GENERIC
  852. + # The main bus device
  853. + mainbus0 at root
  854. + # The boot cpu
  855. + cpu0 at mainbus?
  856. + # The hydra multiprocessor device
  857. + hydrabus0 at mainbus?
  858. + #hcpu0 at hydrabus?
  859. + #hcpu1 at hydrabus? slot 0
  860. + #hcpu2 at hydrabus?
  861. + #hcpu3 at hydrabus?
  862. + # The vidc
  863. + vidcvideo0    at mainbus?
  864. + # generic VT console device
  865. + vt0     at mainbus?
  866. + vt1     at mainbus?
  867. + vt2     at mainbus?
  868. + vt3     at mainbus?
  869. + vt4     at mainbus?
  870. + vt5     at mainbus?
  871. + # IDE disk controller
  872. + wdc0    at mainbus? base 0x002107c0 irq 9
  873. + wd*     at wdc? drive ?
  874. + # Floppy disk controller
  875. + fdc0    at mainbus? base 0x00210fc0 irq 12 dack 0x00002000
  876. + fd0     at fdc? drive ?
  877. + # kbd via IOMD
  878. + kbd0    at mainbus? base 0x00000000
  879. + # quadrature mouse
  880. + quadmouse0    at mainbus? base 0x00000000 irq 6    # TMR1
  881. + #quadmouse0    at mainbus? base 0x00000000 irq 3    # VSYNC
  882. + # PS2 mouse
  883. + pms0    at mainbus? base 0x00000000
  884. + # Serial ports
  885. + com0    at mainbus? base 0x00210fe0 irq 10
  886. + #com1    at mainbus? base 0x00210be0
  887. + # Parallel ports
  888. + lpt0    at mainbus? base 0x002109e0 irq 0
  889. + # Crude sound device
  890. + beep0    at mainbus? base 0x00000000
  891. + # IIC bus device
  892. + iic0    at mainbus?
  893. + # RTC device
  894. + rtc0    at iic? addr 0xa0
  895. + # Podule bus device
  896. + podulebus0    at root
  897. + asc0    at podulebus?            # Acorn SCSI card
  898. + scsibus* at asc?
  899. + csc0    at podulebus?            # Cumana SCSI II card
  900. + scsibus* at csc?
  901. + ptsc0    at podulebus?            # Power-Tec SCSI II card
  902. + scsibus* at ptsc?
  903. + oak0    at podulebus?            # Oak SCSI I card
  904. + scsibus* at oak?
  905. + sd*    at scsibus? target ? lun ?    # SCSI disk drives
  906. + st*    at scsibus? target ? lun ?    # SCSI tape drives
  907. + cd*    at scsibus? target ? lun ?    # SCSI CD-ROM drives
  908. + ch*    at scsibus? target ? lun ?    # SCSI auto-changers
  909. + uk*    at scsibus? target ? lun ?    # SCSI unknown device
  910. + ss*    at scsibus? target ? lun ?    # SCSI scanner
  911. + #kie*    at podulebus? slot ? offset ?
  912. + ea0    at podulebus?            # Ether3 podules
  913. + eb0    at podulebus?            # EtherB network slot cards
  914. + eh0    at podulebus?            # EtherH network slot cards
  915. + ie0    at podulebus?            # Ether1 podules
  916. + pseudo-device    loop    1               # network loopback
  917. + pseudo-device   bpfilter 8              # packet filter
  918. + pseudo-device    sl    2               # CSLIP
  919. + pseudo-device    ppp    2        # PPP
  920. + pseudo-device    tun    2        # network tunneling over tty
  921. + pseudo-device   pty     32              # pseudo-terminals
  922. + pseudo-device    tb    1        # tablet line discipline
  923. + pseudo-device   vnd     4               # paging to files
  924. + pseudo-device    ccd    2        # concatenated disk devices
  925. + pseudo-device    rd    1        # Ramdisk device
  926. + makeoptions MONITOR="Taxan875+LR"
  927. + #makeoptions MONITOR="AKF60"
  928. + makeoptions MODES="1024,768,60 1024,768,70 800,600,60 640,480,60 1280,1024 1152,900"
  929. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/conf/files.arm32 sys/arch/arm32/conf/files.arm32
  930. *** sys/arch/arm32.orig/conf/files.arm32    Thu Jun 13 02:17:41 1996
  931. --- sys/arch/arm32/conf/files.arm32    Thu Jun 13 02:56:55 1996
  932. ***************
  933. *** 39,50 ****
  934.   file    arch/arm32/arm32/kgdb_glue.c        kgdb needs-flag
  935.   file    arch/arm32/arm32/kgdb_step.c        kgdb
  936.   
  937.   # Standard NetBSD wd driver
  938. ! device  wdc {drive = -1}
  939.   attach    wdc at mainbus
  940.   device  wd: disk
  941. ! attach    wd at wdc
  942.   file    arch/arm32/mainbus/wd.c            wdc needs-flag
  943.   major   {wd = 16}
  944.   
  945.   # Standard NetBSD fd driver
  946. --- 39,57 ----
  947.   file    arch/arm32/arm32/kgdb_glue.c        kgdb needs-flag
  948.   file    arch/arm32/arm32/kgdb_step.c        kgdb
  949.   
  950. + #
  951. + # Machine-independent ATAPI drivers
  952. + #
  953. + include "../../../atapi/files.atapi"
  954.   # Standard NetBSD wd driver
  955. ! define ata {drive=-1}
  956. ! device  wdc: atapi, ata 
  957.   attach    wdc at mainbus
  958.   device  wd: disk
  959. ! attach  wd at ata
  960.   file    arch/arm32/mainbus/wd.c            wdc needs-flag
  961. + file    arch/arm32/mainbus/wdc.c        wdc needs-flag
  962.   major   {wd = 16}
  963.   
  964.   # Standard NetBSD fd driver
  965. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/conf/files.arm32.orig sys/arch/arm32/conf/files.arm32.orig
  966. *** sys/arch/arm32.orig/conf/files.arm32.orig    Thu Jan  1 01:00:00 1970
  967. --- sys/arch/arm32/conf/files.arm32.orig    Thu Jun 13 02:17:41 1996
  968. ***************
  969. *** 0 ****
  970. --- 1,276 ----
  971. + #
  972. + # First try for arm-specific configuration info
  973. + #
  974. + maxpartitions    8
  975. + maxusers 2 8 64
  976. + device mainbus { [base = -1], [dack = -1], [irq = -1] }
  977. + attach mainbus at root
  978. + file    arch/arm32/mainbus/mainbus.c        mainbus
  979. + device cpu
  980. + attach cpu at mainbus
  981. + file    arch/arm32/mainbus/cpu.c        cpu needs-flag
  982. + major    {cpu = 38}
  983. + device hydrabus { [slot = -1] }
  984. + attach hydrabus at mainbus
  985. + file    arch/arm32/mainbus/exp/hydrabus.c    hydrabus needs-flag
  986. + device hcpu
  987. + attach hcpu at hydrabus
  988. + file    arch/arm32/mainbus/exp/hcpu.c        hcpu needs-count
  989. + file    arch/arm32/mainbus/exp/hydraboot.S    hydrabus | hcpu
  990. + file    arch/arm32/mainbus/exp/hydra.c        hydrabus | hcpu
  991. + #
  992. + # Machine-independent KGDB support
  993. + #
  994. + #include "../../../kgdb/files.kgdb"
  995. + define    kgdb
  996. + device    kgdbslip: kgdb
  997. + device    kgdbppp: kgdb
  998. + #device kie
  999. + #attach kie at podule
  1000. + #file    arch/arm32/podulebus/kgdb_ie.c        kie
  1001. + file    arch/arm32/arm32/kgdb_glue.c        kgdb needs-flag
  1002. + file    arch/arm32/arm32/kgdb_step.c        kgdb
  1003. + # Standard NetBSD wd driver
  1004. + device  wdc {drive = -1}
  1005. + attach    wdc at mainbus
  1006. + device  wd: disk
  1007. + attach    wd at wdc
  1008. + file    arch/arm32/mainbus/wd.c            wdc needs-flag
  1009. + major   {wd = 16}
  1010. + # Standard NetBSD fd driver
  1011. + device  fdc {drive = -1}
  1012. + attach    fdc at mainbus
  1013. + device  fd: disk
  1014. + attach    fd at fdc
  1015. + file    arch/arm32/mainbus/fd.c            fdc needs-flag
  1016. + major   {fd = 17}
  1017. + # RAM disk driver
  1018. + pseudo-device    rd
  1019. + file    dev/ramdisk.c                rd needs-count
  1020. + file    arch/arm32/dev/rd_hooks.c        rd | ramdisk_hooks
  1021. + major   {rd = 18}
  1022. + # Standard parallal driver
  1023. + device  lpt: tty, ether, ifnet
  1024. + attach    lpt at mainbus
  1025. + file    arch/arm32/mainbus/lpt.c        lpt needs-flag
  1026. + major   {lpt = 8}
  1027. + # Standard serial driver
  1028. + define    kgdbcom {[ disable = 0], [ address = 0x12345678 ], [ speed = 9600 ]}
  1029. + device  com: tty, kgdbcom
  1030. + attach  com at mainbus
  1031. + file    arch/arm32/mainbus/com.c        com | kgdb_cslp | kgdb_cppp needs-flag
  1032. + major   {com = 12}
  1033. + attach    kgdbslip at kgdbcom with kgdb_cslp
  1034. + attach    kgdbppp at kgdbcom with kgdb_cppp
  1035. + # Mouse devices
  1036. + device  quadmouse: tty
  1037. + attach    quadmouse at mainbus
  1038. + file    arch/arm32/mainbus/qmouse.c        quadmouse needs-flag
  1039. + major   {quadmouse = 9}
  1040. + device  pms: tty
  1041. + attach    pms at mainbus
  1042. + file    arch/arm32/mainbus/pms.c        pms needs-flag
  1043. + major   {pms = 40}
  1044. + # Audio devices
  1045. + device    beep
  1046. + attach    beep at mainbus
  1047. + file    arch/arm32/mainbus/beep.c        beep needs-flag
  1048. + major   {beep = 10}
  1049. + device    audio: audio
  1050. + attach    audio at mainbus
  1051. + file    arch/arm32/mainbus/vidcaudio.c        vidcaudio needs-flag
  1052. + major   {audio = 36}
  1053. + # Standard keyboard driver
  1054. + device    kbd
  1055. + attach    kbd at mainbus
  1056. + file    arch/arm32/mainbus/kbd.c        kbd needs-flag
  1057. + major   {kbd = 11}
  1058. + # Podule bus device
  1059. + device podulebus { [slot = -1] }
  1060. + attach podulebus at root
  1061. + file    arch/arm32/podulebus/podulebus.c    podulebus needs-flag
  1062. + # Ethernet devices
  1063. + device ea: ether, ifnet
  1064. + attach ea at podulebus
  1065. + file    arch/arm32/podulebus/if_ea.c        ea
  1066. + device eb: ether, ifnet
  1067. + attach eb at podulebus
  1068. + file    arch/arm32/podulebus/if_eb.c        eb
  1069. + device eh: ether, ifnet
  1070. + attach eh at podulebus
  1071. + file    arch/arm32/podulebus/if_eh.c        eh
  1072. + device ie: ether, ifnet
  1073. + attach ie at podulebus
  1074. + file    arch/arm32/podulebus/if_ie.c        ie
  1075. + device es: ether, ifnet
  1076. + attach es at mainbus
  1077. + file  arch/arm32/mainbus/if_es.c              es
  1078. + # IIC/RTC files
  1079. + device iic { addr = -1 }
  1080. + attach iic at mainbus
  1081. + file    arch/arm32/mainbus/iic_asm.S        iic
  1082. + file    arch/arm32/mainbus/iic.c        iic    needs-flag
  1083. + device rtc
  1084. + attach rtc at iic
  1085. + file    arch/arm32/mainbus/rtc.c        rtc    needs-count
  1086. + #
  1087. + # Machine-independent SCSI drivers
  1088. + #
  1089. + include "../../../scsi/files.scsi"
  1090. + major   {sd = 24}
  1091. + major   {st = 25}
  1092. + major   {cd = 26}
  1093. + major   {ch = 27}
  1094. + major    {uk = 28}
  1095. + major    {ss = 29}
  1096. + # Generic sbic (WD3393) driver
  1097. + define    sbic
  1098. + file    arch/arm32/podulebus/sbic.c        sbic
  1099. + # Acorn SCSI I specific layer for sbic
  1100. + device  asc: scsi, sbic
  1101. + attach    asc at podulebus
  1102. + file    arch/arm32/podulebus/asc.c        asc needs-flag
  1103. + # Generic fas216 + esp216 driver
  1104. + define    sfas
  1105. + file    arch/arm32/podulebus/sfas.c        sfas
  1106. + # Cumana specific layer for sfas
  1107. + device    csc: scsi, sfas
  1108. + attach    csc at podulebus
  1109. + file    arch/arm32/podulebus/exp/csc.c        csc
  1110. + device    ptsc: scsi, sfas
  1111. + attach    ptsc at podulebus
  1112. + file    arch/arm32/podulebus/ptsc.c        ptsc
  1113. + # Generic NCR driver
  1114. + define    ncr
  1115. + file    arch/arm32/podulebus/ncr5380sbc.c    ncr
  1116. + # Oak specific layer for ncr
  1117. + device    oak: scsi, ncr
  1118. + attach    oak at podulebus
  1119. + file    arch/arm32/podulebus/oak.c    oak
  1120. + device  vidcvideo
  1121. + attach    vidcvideo at mainbus
  1122. + major    {vidcvideo = 37}
  1123. + device  vt: tty
  1124. + attach    vt at mainbus
  1125. + file    arch/arm32/dev/console/console.c    vt needs-count
  1126. + file    arch/arm32/dev/console/vidcconsole.c    vt needs-count
  1127. + file    arch/arm32/dev/console/vidc_mc.S    vt needs-count
  1128. + file    arch/arm32/dev/console/vidc.c        vt needs-count
  1129. + file    arch/arm32/dev/console/vt220.c        vt needs-count
  1130. + file    arch/arm32/dev/console/debugconsole.c     vt needs-count
  1131. + file    arch/arm32/dev/console/dumb.c         vt needs-count
  1132. + file    arch/arm32/arm32/autoconf.c
  1133. + file    arch/arm32/arm32/blockio.S
  1134. + file    arch/arm32/arm32/clock.c
  1135. + file    arch/arm32/arm32/conf.c
  1136. + file    arch/arm32/arm32/cpuswitch.S
  1137. + file    arch/arm32/arm32/disksubr.c        disk
  1138. + file    arch/arm32/arm32/stubs.c
  1139. + file    arch/arm32/arm32/exception.S
  1140. + file    arch/arm32/arm32/syscall.c
  1141. + file    arch/arm32/arm32/ast.c
  1142. + file    arch/arm32/arm32/fault.c
  1143. + file    arch/arm32/arm32/undefined.c
  1144. + file    arch/arm32/arm32/mem.c
  1145. + file    arch/arm32/arm32/scratch.S
  1146. + file    arch/arm32/arm32/process_machdep.c
  1147. + file    arch/arm32/arm32/machdep.c
  1148. + file    arch/arm32/arm32/sys_machdep.c
  1149. + file    arch/arm32/arm32/vm_machdep.c
  1150. + file    arch/arm32/arm32/pmap.c
  1151. + file    arch/arm32/arm32/fusu.c
  1152. + file    netinet/in_cksum.c            inet
  1153. + file    netns/ns_cksum.c            ns
  1154. + # IRQ/FIQ files
  1155. + file    arch/arm32/arm32/spl.S
  1156. + file    arch/arm32/arm32/irq.S
  1157. + file    arch/arm32/arm32/irqhandler.c
  1158. + file    arch/arm32/arm32/fiq.S
  1159. + # library functions
  1160. + file    arch/arm32/arm32/strstr.c
  1161. + file    arch/arm32/arm32/strtoul.c
  1162. + file    arch/arm32/arm32/memset.S
  1163. + file    arch/arm32/arm32/bcopy_page.S
  1164. + file    arch/arm32/arm32/bcopy.S
  1165. + file    arch/arm32/arm32/bcopyinout.S
  1166. + file    arch/arm32/arm32/copystr.S
  1167. + file    arch/arm32/arm32/coproc15.S
  1168. + file    arch/arm32/arm32/setcpsr.S
  1169. + file    arch/arm32/arm32/setstack.S
  1170. + # files related to the shell
  1171. + file    arch/arm32/kshell/shell_input.c        kshell
  1172. + file    arch/arm32/kshell/shell_shell.c        kshell
  1173. + file    arch/arm32/kshell/shell_disassem.c    kshell
  1174. + file    arch/arm32/kshell/strchr.c        kshell
  1175. + file    arch/arm32/kshell/dumphex.c        kshell
  1176. + # files related to debugging
  1177. + file    arch/arm32/arm32/debug.c
  1178. + file    arch/arm32/arm32/disassem.c
  1179. + file    arch/arm32/arm32/postmortem.c
  1180. +  
  1181. + file    dev/cons.c
  1182. + file    dev/cninit.c
  1183. + # Signal precision FPE
  1184. + file    arch/arm32/fpe-sp/fpe.c            fpe
  1185. + file    arch/arm32/fpe-sp/fpeadd.S        fpe
  1186. + file    arch/arm32/fpe-sp/fpesub.S        fpe
  1187. + file    arch/arm32/fpe-sp/fpemul.S        fpe
  1188. + file    arch/arm32/fpe-sp/fpediv.S        fpe
  1189. + file    arch/arm32/fpe-sp/fpefix.S        fpe
  1190. + file    arch/arm32/fpe-sp/fpecmf.S        fpe
  1191. + file    arch/arm32/fpe-sp/fpetoe.S        fpe
  1192. + # ARM FPE
  1193. + file    arch/arm32/fpe-arm/armfpe_glue.S    armfpe
  1194. + file    arch/arm32/fpe-arm/armfpe_init.c    armfpe
  1195. + file    arch/arm32/fpe-arm/armfpe.s        armfpe
  1196. + # DDB
  1197. + file    arch/arm32/arm32/db_disasm.c        ddb
  1198. + file    arch/arm32/arm32/db_interface.c        ddb
  1199. + file    arch/arm32/arm32/db_trace.c        ddb
  1200. + file    arch/arm32/arm32/db_machdep.c        ddb
  1201. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/mainbus/wd.c sys/arch/arm32/mainbus/wd.c
  1202. *** sys/arch/arm32.orig/mainbus/wd.c    Wed Jun 12 22:41:10 1996
  1203. --- sys/arch/arm32/mainbus/wd.c    Thu Jun 13 03:11:10 1996
  1204. ***************
  1205. *** 57,76 ****
  1206.   #include <machine/io.h>
  1207.   #include <machine/katelib.h>
  1208.   
  1209. - #include <arm32/mainbus/wdreg.h>
  1210.   #include <arm32/mainbus/mainbus.h>
  1211. ! extern int wdresethack;
  1212.   #define    WAITTIME    (4 * hz)    /* time to wait for a completion */
  1213. - #define    RECOVERYTIME    (hz / 2)    /* time to recover from an error */
  1214. - #define WDCDELAY    100
  1215. - #define WDCNDELAY    100000        /* delay = 100us; so 10s for a controller state change */
  1216. - #if 0
  1217. - /* If you enable this, it will report any delays more than 100us * N long. */
  1218. - #define WDCNDELAY_DEBUG    10
  1219. - #endif
  1220.   
  1221.   #define    WDIORETRIES    5        /* number of retries before giving up */
  1222.   
  1223. --- 57,67 ----
  1224.   #include <machine/io.h>
  1225.   #include <machine/katelib.h>
  1226.   
  1227.   #include <arm32/mainbus/mainbus.h>
  1228. ! #include <arm32/mainbus/wdreg.h>
  1229. ! #include <arm32/mainbus/wdlink.h>
  1230. !   
  1231.   #define    WAITTIME    (4 * hz)    /* time to wait for a completion */
  1232.   
  1233.   #define    WDIORETRIES    5        /* number of retries before giving up */
  1234.   
  1235. ***************
  1236. *** 83,303 ****
  1237.   struct wd_softc {
  1238.       struct device sc_dev;
  1239.       struct disk sc_dk;
  1240. !     /* Information about the current transfer: */
  1241. !     daddr_t sc_blkno;    /* starting block number */
  1242. !     int sc_bcount;        /* byte count left */
  1243. !     int sc_skip;        /* bytes already transferred */
  1244. !     int sc_nblks;        /* number of blocks currently transferring */
  1245. !     int sc_nbytes;        /* number of bytes currently transferring */
  1246. !     /* Long-term state: */
  1247. !     int sc_drive;            /* physical unit number */
  1248. !     int sc_state;            /* control state */
  1249. ! #define    RECAL        0        /* recalibrate */
  1250. ! #define    RECAL_WAIT    1        /* done recalibrating */
  1251. ! #define    GEOMETRY    2        /* upload geometry */
  1252. ! #define    GEOMETRY_WAIT    3        /* done uploading geometry */
  1253. ! #define    MULTIMODE    4        /* set multiple mode */
  1254. ! #define    MULTIMODE_WAIT    5        /* done setting multiple mode */
  1255. ! #define    OPEN        6        /* done with open */
  1256. !     int sc_mode;            /* transfer mode */
  1257. ! #define    WDM_PIOSINGLE    0        /* single-sector PIO */
  1258. ! #define    WDM_PIOMULTI    1        /* multi-sector PIO */
  1259. ! #define    WDM_DMA        2        /* DMA */
  1260. !     int sc_multiple;        /* multiple for WDM_PIOMULTI */
  1261. !     int sc_flags;            /* drive characteistics found */
  1262. ! #define    WDF_LOCKED    0x01
  1263. ! #define    WDF_WANTED    0x02
  1264. ! #define    WDF_WLABEL    0x04        /* label is writable */
  1265. ! #define    WDF_LABELLING    0x08        /* writing label */
  1266. ! /* XXX Nothing resets this yet, but disk change sensing will when ATAPI is
  1267. !    implemented. */
  1268. ! #define    WDF_LOADED    0x10        /* parameters loaded */
  1269. ! #define    WDF_32BIT    0x20        /* can do 32-bit transfer */
  1270. !     struct wdparams sc_params;    /* ESDI/ATA drive parameters */
  1271. !     daddr_t    sc_badsect[127];    /* 126 plus trailing -1 marker */
  1272. !     TAILQ_ENTRY(wd_softc) sc_drivechain;
  1273.       struct buf sc_q;
  1274.   };
  1275.   
  1276. ! struct wdc_softc {
  1277. !     struct device sc_dev;
  1278. !     irqhandler_t sc_ih;
  1279. !     int sc_iobase;            /* I/O port base */
  1280. !     int sc_drq;            /* DMA channel */
  1281. !     TAILQ_HEAD(drivehead, wd_softc) sc_drives;
  1282. !     int sc_flags;
  1283. ! #define    WDCF_ACTIVE    0x01        /* controller is active */
  1284. ! #define    WDCF_SINGLE    0x02        /* sector at a time mode */
  1285. ! #define    WDCF_ERROR    0x04        /* processing a disk error */
  1286. ! #define    WDCF_WANTED    0x08        /* XXX locking for wd_get_parms() */
  1287. !     int sc_errors;            /* errors during current transfer */
  1288. !     u_char sc_status;        /* copy of status register */
  1289. !     u_char sc_error;        /* copy of error register */
  1290. ! };
  1291. ! int    wdcprobe     __P((struct device *, void *, void *));
  1292. ! void    wdcattach     __P((struct device *, struct device *, void *));
  1293. ! int    wdcintr        __P((void *));
  1294. ! struct cfattach wdc_ca = {
  1295. !     sizeof(struct wdc_softc), wdcprobe, wdcattach
  1296. ! };
  1297.   
  1298. ! struct cfdriver wdc_cd = {
  1299. !     NULL, "wdc", DV_DULL
  1300.   };
  1301.   
  1302. - int    wdprobe        __P((struct device *, void *, void *));
  1303. - void    wdattach    __P((struct device *, struct device *, void *));
  1304. - int    wdprint        __P((void *, char *));
  1305.   struct cfattach wd_ca = {
  1306.       sizeof(struct wd_softc), wdprobe, wdattach
  1307.   };
  1308.   
  1309. - struct cfdriver wd_cd = {
  1310. -     NULL, "wd", DV_DISK
  1311. - };
  1312.   
  1313. ! void    wdgetdisklabel    __P((struct wd_softc *));
  1314. ! int    wd_get_parms    __P((struct wd_softc *));
  1315. ! void    wdstrategy    __P((struct buf *));
  1316. ! void    wdstart        __P((struct wd_softc *));
  1317.   
  1318.   struct dkdriver wddkdriver = { wdstrategy };
  1319.   
  1320. ! /* XXX: these should go elsewhere */
  1321. ! cdev_decl(wd);
  1322. ! bdev_decl(wd);
  1323. ! void    wdfinish    __P((struct wd_softc *, struct buf *));
  1324. ! int     dcintr        __P((void *));
  1325. ! void    wdcstart    __P((struct wdc_softc *));
  1326. ! int    wdcommand    __P((struct wd_softc *, int, int, int, int, int));
  1327. ! int    wdcommandshort    __P((struct wdc_softc *, int, int));
  1328. ! int    wdcontrol    __P((struct wd_softc *));
  1329. ! int    wdsetctlr    __P((struct wd_softc *));
  1330. ! static void bad144intern __P((struct wd_softc *));
  1331. ! int    wdcreset    __P((struct wdc_softc *));
  1332. ! void    wdcrestart    __P((void *arg));
  1333. ! void    wdcunwedge    __P((struct wdc_softc *));
  1334. ! void    wdctimeout    __P((void *arg));
  1335. ! void    wderror        __P((void *, struct buf *, char *));
  1336. ! int    wdcwait        __P((struct wdc_softc *, int));
  1337. ! int    wdlock        __P((struct wd_softc *));
  1338. ! void    wdunlock    __P((struct wd_softc *));
  1339. ! /* ST506 spec says that if READY or SEEKCMPLT go off, then the read or write
  1340. !    command is aborted. */
  1341. ! #define    wait_for_drq(d)        wdcwait(d, WDCS_DRDY | WDCS_DSC | WDCS_DRQ)
  1342. ! #define    wait_for_ready(d)    wdcwait(d, WDCS_DRDY | WDCS_DSC)
  1343. ! #define    wait_for_unbusy(d)    wdcwait(d, 0)
  1344. ! int
  1345. ! wdcprobe(parent, match, aux)
  1346. !     struct device *parent;
  1347. !     void *match, *aux;
  1348. ! {
  1349. !     struct wdc_softc *wdc = match;
  1350. !     struct mainbus_attach_args *mb = aux;
  1351. !     int iobase;
  1352. !     wdc->sc_iobase = iobase = mb->mb_iobase;
  1353. !     /* Check if we have registers that work. */
  1354. !     outb(iobase+wd_error, 0x5a);    /* Error register not writable, */
  1355. !     outb(iobase+wd_cyl_lo, 0xa5);    /* but all of cyllo are. */
  1356. !     if (inb(iobase+wd_error) == 0x5a || inb(iobase+wd_cyl_lo) != 0xa5)
  1357. !         return 0;
  1358. !     if (wdcreset(wdc) != 0) {
  1359. !         delay(500000);
  1360. !         if (wdcreset(wdc) != 0)
  1361. !             return 0;
  1362. !     }
  1363. !     /* Select drive 0. */
  1364. !     outb(iobase+wd_sdh, WDSD_IBM | 0);
  1365. !     /* Wait for controller to become ready. */
  1366. !     if (wait_for_unbusy(wdc) < 0)
  1367. !         return 0;
  1368. !     
  1369. !     /* Start drive diagnostics. */
  1370. !     outb(iobase+wd_command, WDCC_DIAGNOSE);
  1371. !     /* Wait for command to complete. */
  1372. !     if (wait_for_unbusy(wdc) < 0)
  1373. !         return 0;
  1374. !     mb->mb_iosize = 32;
  1375. !     return 1;
  1376. ! }
  1377. ! struct wdc_attach_args {
  1378. !     int wa_drive;
  1379. ! };
  1380.   
  1381. ! int
  1382. ! wdprint(aux, wdc)
  1383. !     void *aux;
  1384. !     char *wdc;
  1385. ! {
  1386. !     struct wdc_attach_args *wa = aux;
  1387. !     if (!wdc)
  1388. !         printf(" drive %d", wa->wa_drive);
  1389. !     return QUIET;
  1390. ! }
  1391. ! void
  1392. ! wdcattach(parent, self, aux)
  1393. !     struct device *parent, *self;
  1394. !     void *aux;
  1395. ! {
  1396. !     struct wdc_softc *wdc = (void *)self;
  1397. !     struct mainbus_attach_args *mb = aux;
  1398. !     struct wdc_attach_args wa;
  1399. !     TAILQ_INIT(&wdc->sc_drives);
  1400. !     wdc->sc_drq = mb->mb_drq;
  1401. !     printf("\n");
  1402. !       wdc->sc_ih.ih_func = wdcintr;
  1403. !        wdc->sc_ih.ih_arg = wdc;
  1404. !        wdc->sc_ih.ih_level = IPL_BIO;
  1405. !        wdc->sc_ih.ih_name = "wdc";
  1406. !     if (irq_claim(mb->mb_irq, &wdc->sc_ih))
  1407. !         panic("Cannot claim IRQ %d for wdc%d\n", mb->mb_irq, parent->dv_unit);
  1408. !     for (wa.wa_drive = 0; wa.wa_drive < 2; wa.wa_drive++)
  1409. !         (void)config_found(self, (void *)&wa, wdprint);
  1410. ! }
  1411.   
  1412.   int
  1413.   wdprobe(parent, match, aux)
  1414.       struct device *parent;
  1415.       void *match, *aux;
  1416.   {
  1417. !     struct wdc_softc *wdc = (void *)parent;
  1418.       struct cfdata *cf = match;
  1419. !     struct wdc_attach_args *wa = aux;
  1420. !     int drive = wa->wa_drive;
  1421. !     if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != drive)
  1422. !         return 0;
  1423.       
  1424. !     if (wdcommandshort(wdc, drive, WDCC_RECAL) != 0 ||
  1425. !         wait_for_ready(wdc) != 0)
  1426.           return 0;
  1427.       return 1;
  1428.   }
  1429.   
  1430. --- 74,123 ----
  1431.   struct wd_softc {
  1432.       struct device sc_dev;
  1433.       struct disk sc_dk;
  1434. !     struct wd_link *d_link;
  1435.       struct buf sc_q;
  1436.   };
  1437.   
  1438. ! int wdprobe    __P((struct device *, void *, void *));
  1439. ! void wdattach    __P((struct device *, struct device *, void *));
  1440.   
  1441. ! struct cfdriver wd_cd = {
  1442. !     NULL, "wd", DV_DISK
  1443.   };
  1444.   
  1445.   struct cfattach wd_ca = {
  1446.       sizeof(struct wd_softc), wdprobe, wdattach
  1447.   };
  1448.   
  1449.   
  1450. ! void wdgetdisklabel __P((struct wd_softc *));
  1451. ! void wdstrategy __P((struct buf *));
  1452. ! void wdstart __P((struct wd_softc *));
  1453.   
  1454.   struct dkdriver wddkdriver = { wdstrategy };
  1455.   
  1456. ! int wdlock __P((struct wd_link *));
  1457. ! void wdunlock __P((struct wd_link *));
  1458.   
  1459. ! int wdsetctlr __P((struct wd_link *));
  1460. ! static void bad144intern __P((struct wd_softc *));
  1461. ! int wdcdump __P((struct wd_link *, daddr_t blkno, int nblks, caddr_t va));
  1462.   
  1463.   int
  1464.   wdprobe(parent, match, aux)
  1465.       struct device *parent;
  1466.       void *match, *aux;
  1467.   {
  1468. ! /*    caddr_t *wdc = (void *)parent;*/
  1469.       struct cfdata *cf = match;
  1470. !     struct wd_link *d_link = aux;
  1471. !     int drive;
  1472.       
  1473. !     if (d_link == NULL ) return 0;
  1474. !     if (d_link-> type != DRIVE) return 0;
  1475. !     drive = d_link->sc_drive;
  1476. !     if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != drive)
  1477.           return 0;
  1478.       return 1;
  1479.   }
  1480.   
  1481. ***************
  1482. *** 307,329 ****
  1483.       void *aux;
  1484.   {
  1485.       struct wd_softc *wd = (void *)self;
  1486. !     struct wdc_softc *wdc = (void *)parent;
  1487. !     struct wdc_attach_args *wa = aux;
  1488.       int i, blank;
  1489.       char buf[41], c, *p, *q;
  1490.   
  1491. !     wd->sc_drive = wa->wa_drive;
  1492.   
  1493. !     /*
  1494. !      * Initialize and attach the disk structure.
  1495.        */
  1496.       wd->sc_dk.dk_driver = &wddkdriver;
  1497.       wd->sc_dk.dk_name = wd->sc_dev.dv_xname;
  1498.       disk_attach(&wd->sc_dk);
  1499.   
  1500. !     wd_get_parms(wd);
  1501. !     for (blank = 0, p = wd->sc_params.wdp_model, q = buf, i = 0;
  1502. !          i < sizeof(wd->sc_params.wdp_model); i++) {
  1503.           c = *p++;
  1504.           if (c == '\0')
  1505.               break;
  1506. --- 127,153 ----
  1507.       void *aux;
  1508.   {
  1509.       struct wd_softc *wd = (void *)self;
  1510. ! /*    struct caddr_t *wdc = (void *)parent;*/
  1511. !     struct wd_link *d_link= aux;
  1512.       int i, blank;
  1513.       char buf[41], c, *p, *q;
  1514.   
  1515. !     wd->d_link = d_link;
  1516. !     d_link->openings = 1;
  1517. !     d_link->wd_softc = (caddr_t)wd;
  1518.   
  1519. !      /*
  1520. !          * Initialize and attach the disk structure.
  1521.        */
  1522.       wd->sc_dk.dk_driver = &wddkdriver;
  1523.       wd->sc_dk.dk_name = wd->sc_dev.dv_xname;
  1524.       disk_attach(&wd->sc_dk);
  1525.   
  1526. !     d_link->sc_lp = wd->sc_dk.dk_label;
  1527. !     wdc_get_parms(d_link);
  1528. !     for (blank = 0, p = d_link->sc_params.wdp_model, q = buf, i = 0;
  1529. !          i < sizeof(d_link->sc_params.wdp_model); i++) {
  1530.           c = *p++;
  1531.           if (c == '\0')
  1532.               break;
  1533. ***************
  1534. *** 339,371 ****
  1535.       *q++ = '\0';
  1536.   
  1537.       printf(": %dMB, %d cyl, %d head, %d sec, %d bytes/sec <%s>\n",
  1538. !         wd->sc_params.wdp_cylinders *
  1539. !         (wd->sc_params.wdp_heads * wd->sc_params.wdp_sectors) /
  1540.           (1048576 / DEV_BSIZE),
  1541. !         wd->sc_params.wdp_cylinders,
  1542. !         wd->sc_params.wdp_heads,
  1543. !         wd->sc_params.wdp_sectors,
  1544.           DEV_BSIZE,
  1545.           buf);
  1546.   
  1547. !     if ((wd->sc_params.wdp_capabilities & WD_CAP_DMA) != 0 &&
  1548. !         wdc->sc_drq != DRQUNK) {
  1549. !         wd->sc_mode = WDM_DMA;
  1550. !     } else if (wd->sc_params.wdp_maxmulti > 1) {
  1551. !         wd->sc_mode = WDM_PIOMULTI;
  1552. !         wd->sc_multiple = min(wd->sc_params.wdp_maxmulti, 16);
  1553.       } else {
  1554. !         wd->sc_mode = WDM_PIOSINGLE;
  1555. !         wd->sc_multiple = 1;
  1556.       }
  1557.   
  1558.       printf("%s: using", wd->sc_dev.dv_xname);
  1559. !     if (wd->sc_mode == WDM_DMA)
  1560.           printf(" dma transfers,");
  1561.       else
  1562.           printf(" %d-sector %d-bit pio transfers,",
  1563. !             wd->sc_multiple, (wd->sc_flags & WDF_32BIT) == 0 ? 16 : 32);
  1564. !     if ((wd->sc_params.wdp_capabilities & WD_CAP_LBA) != 0)
  1565.           printf(" lba addressing\n");
  1566.       else
  1567.           printf(" chs addressing\n");
  1568. --- 163,195 ----
  1569.       *q++ = '\0';
  1570.   
  1571.       printf(": %dMB, %d cyl, %d head, %d sec, %d bytes/sec <%s>\n",
  1572. !         d_link->sc_params.wdp_cylinders *
  1573. !         (d_link->sc_params.wdp_heads * d_link->sc_params.wdp_sectors) /
  1574.           (1048576 / DEV_BSIZE),
  1575. !         d_link->sc_params.wdp_cylinders,
  1576. !         d_link->sc_params.wdp_heads,
  1577. !         d_link->sc_params.wdp_sectors,
  1578.           DEV_BSIZE,
  1579.           buf);
  1580.   
  1581. !     if ((d_link->sc_params.wdp_capabilities & WD_CAP_DMA) != 0 &&
  1582. !         d_link->sc_mode == WDM_DMA) {
  1583. !         d_link->sc_mode = WDM_DMA;
  1584. !     } else if (d_link->sc_params.wdp_maxmulti > 1) {
  1585. !         d_link->sc_mode = WDM_PIOMULTI;
  1586. !         d_link->sc_multiple = min(d_link->sc_params.wdp_maxmulti, 16);
  1587.       } else {
  1588. !         d_link->sc_mode = WDM_PIOSINGLE;
  1589. !         d_link->sc_multiple = 1;
  1590.       }
  1591.   
  1592.       printf("%s: using", wd->sc_dev.dv_xname);
  1593. !     if (d_link->sc_mode == WDM_DMA)
  1594.           printf(" dma transfers,");
  1595.       else
  1596.           printf(" %d-sector %d-bit pio transfers,",
  1597. !             d_link->sc_multiple, (d_link->sc_flags & WDF_32BIT) == 0 ? 16 : 32);
  1598. !     if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0)
  1599.           printf(" lba addressing\n");
  1600.       else
  1601.           printf(" chs addressing\n");
  1602. ***************
  1603. *** 380,385 ****
  1604. --- 204,210 ----
  1605.       struct buf *bp;
  1606.   {
  1607.       struct wd_softc *wd = wd_cd.cd_devs[WDUNIT(bp->b_dev)];
  1608. +     struct wd_link *d_link= wd->d_link;
  1609.       int s;
  1610.       
  1611.       /* Valid request?  */
  1612. ***************
  1613. *** 391,397 ****
  1614.       }
  1615.       
  1616.       /* If device invalidated (e.g. media change, door open), error. */
  1617. !     if ((wd->sc_flags & WDF_LOADED) == 0) {
  1618.           bp->b_error = EIO;
  1619.           goto bad;
  1620.       }
  1621. --- 216,222 ----
  1622.       }
  1623.       
  1624.       /* If device invalidated (e.g. media change, door open), error. */
  1625. !     if ((d_link->sc_flags & WDF_LOADED) == 0) {
  1626.           bp->b_error = EIO;
  1627.           goto bad;
  1628.       }
  1629. ***************
  1630. *** 406,428 ****
  1631.        */
  1632.       if (WDPART(bp->b_dev) != RAW_PART &&
  1633.           bounds_check_with_label(bp, wd->sc_dk.dk_label,
  1634. !         (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)
  1635.           goto done;
  1636.       
  1637.       /* Queue transfer on drive, activate drive and controller if idle. */
  1638.       s = splbio();
  1639.       disksort(&wd->sc_q, bp);
  1640. !     if (!wd->sc_q.b_active)
  1641. !         wdstart(wd);
  1642. ! #if 0
  1643. !     else {
  1644. !         struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
  1645. !         if ((wdc->sc_flags & (WDCF_ACTIVE|WDCF_ERROR)) == 0) {
  1646. !             printf("wdstrategy: controller inactive\n");
  1647. !             wdcstart(wdc);
  1648. !         }
  1649. !     }
  1650. ! #endif
  1651.       splx(s);
  1652.       return;
  1653.       
  1654. --- 231,243 ----
  1655.        */
  1656.       if (WDPART(bp->b_dev) != RAW_PART &&
  1657.           bounds_check_with_label(bp, wd->sc_dk.dk_label,
  1658. !         (d_link->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)
  1659.           goto done;
  1660.       
  1661.       /* Queue transfer on drive, activate drive and controller if idle. */
  1662.       s = splbio();
  1663.       disksort(&wd->sc_q, bp);
  1664. !     wdstart(wd);
  1665.       splx(s);
  1666.       return;
  1667.       
  1668. ***************
  1669. *** 441,497 ****
  1670.   wdstart(wd)
  1671.       struct wd_softc *wd;
  1672.   {
  1673. !     struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
  1674. !     int active = wdc->sc_drives.tqh_first != 0;
  1675. !     /* Link onto controller queue. */
  1676. !     wd->sc_q.b_active = 1;
  1677. !     TAILQ_INSERT_TAIL(&wdc->sc_drives, wd, sc_drivechain);
  1678. !     disk_busy(&wd->sc_dk);
  1679. !     
  1680. !     /* If controller not already active, start it. */
  1681. !     if (!active)
  1682. !         wdcstart(wdc);
  1683. ! }
  1684. ! /*
  1685. !  * Finish an I/O operation.  Clean up the drive and controller state, set the
  1686. !  * residual count, and inform the upper layers that the operation is complete.
  1687. !  */
  1688. ! void
  1689. ! wdfinish(wd, bp)
  1690. !     struct wd_softc *wd;
  1691. !     struct buf *bp;
  1692. ! {
  1693. !     struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
  1694. !     wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR);
  1695. !     wdc->sc_errors = 0;
  1696. !     /*
  1697. !      * Move this drive to the end of the queue to give others a `fair'
  1698. !      * chance.
  1699. !      */
  1700. !     if (wd->sc_drivechain.tqe_next) {
  1701. !         TAILQ_REMOVE(&wdc->sc_drives, wd, sc_drivechain);
  1702. !         if (bp->b_actf) {
  1703. !             TAILQ_INSERT_TAIL(&wdc->sc_drives, wd, sc_drivechain);
  1704. !         } else
  1705. !             wd->sc_q.b_active = 0;
  1706. !     }
  1707. !     bp->b_resid = wd->sc_bcount;
  1708. !     wd->sc_skip = 0;
  1709. !     wd->sc_q.b_actf = bp->b_actf;
  1710. !     disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid));
  1711.   
  1712. !     if (!wd->sc_q.b_actf) {
  1713. !         TAILQ_REMOVE(&wdc->sc_drives, wd, sc_drivechain);
  1714. !         wd->sc_q.b_active = 0;
  1715. !     } else
  1716.           disk_busy(&wd->sc_dk);
  1717. !     biodone(bp);
  1718.   }
  1719.   
  1720.   int
  1721. --- 256,297 ----
  1722.   wdstart(wd)
  1723.       struct wd_softc *wd;
  1724.   {
  1725. !     struct buf *dp, *bp=0;
  1726. !     struct wd_link *d_link = wd->d_link;
  1727. !     struct wdc_link *ctlr_link = d_link->ctlr_link;
  1728. !     struct wdc_xfer *xfer;
  1729. ! /*    int blkno, nblks;*/
  1730. !     u_long p_offset; 
  1731. !     while (d_link->openings > 0) {
  1732. !         /* Is there a buf for us ? */
  1733. !         dp = &wd->sc_q;
  1734. !         if ((bp = dp->b_actf) == NULL)  /* yes, an assign */
  1735. !                      return;
  1736. !         dp->b_actf = bp->b_actf;
  1737. !         
  1738. !         /* 
  1739. !          * Make the command. First lock the device
  1740. !          */
  1741. !         d_link->openings--;
  1742. !         if (WDPART(bp->b_dev) != RAW_PART)
  1743. !             p_offset=wd->sc_dk.dk_label->d_partitions[WDPART(bp->b_dev)].p_offset;
  1744. !         else p_offset=0;
  1745. !         xfer = wdc_get_xfer(ctlr_link,0);
  1746. !         if (xfer == NULL) panic("wdc_xfer");
  1747. !         xfer->d_link = d_link;
  1748. !         xfer->c_bp = bp;
  1749. !         xfer->c_p_offset = p_offset;
  1750. !         xfer->databuf = bp->b_data;
  1751. !         xfer->c_bcount = bp->b_bcount;
  1752. !         xfer->c_flags |= bp->b_flags & (B_READ|B_WRITE);
  1753. !         xfer->c_blkno = bp->b_blkno;
  1754.   
  1755. !         /* Instrumentation. */
  1756.           disk_busy(&wd->sc_dk);
  1757. !         wdc_exec_xfer(wd->d_link,xfer);
  1758. !     }
  1759.   }
  1760.   
  1761.   int
  1762. ***************
  1763. *** 500,506 ****
  1764.       struct uio *uio;
  1765.       int flags;
  1766.   {
  1767.       return (physio(wdstrategy, NULL, dev, B_READ, minphys, uio));
  1768.   }
  1769.   
  1770. --- 300,308 ----
  1771.       struct uio *uio;
  1772.       int flags;
  1773.   {
  1774. ! #ifdef WDDEBUG
  1775. !     printf("wdread\n");
  1776. ! #endif
  1777.       return (physio(wdstrategy, NULL, dev, B_READ, minphys, uio));
  1778.   }
  1779.   
  1780. ***************
  1781. *** 510,884 ****
  1782.       struct uio *uio;
  1783.       int flags;
  1784.   {
  1785. -     return (physio(wdstrategy, NULL, dev, B_WRITE, minphys, uio));
  1786. - }
  1787. - /*
  1788. -  * Start I/O on a controller.  This does the calculation, and starts a read or
  1789. -  * write operation.  Called to from wdstart() to start a transfer, from
  1790. -  * wdcintr() to continue a multi-sector transfer or start the next transfer, or
  1791. -  * wdcrestart() after recovering from an error.
  1792. -  */
  1793. - void
  1794. - wdcstart(wdc)
  1795. -     struct wdc_softc *wdc;
  1796. - {
  1797. -     struct wd_softc *wd;
  1798. -     struct buf *bp;
  1799. -     struct disklabel *lp;
  1800. -     int nblks;
  1801. - #ifdef DIAGNOSTIC
  1802. -     if ((wdc->sc_flags & WDCF_ACTIVE) != 0)
  1803. -         panic("wdcstart: controller still active");
  1804. - #endif
  1805. -     /*
  1806. -      * XXX
  1807. -      * This is a kluge.  See comments in wd_get_parms().
  1808. -      */
  1809. -     if ((wdc->sc_flags & WDCF_WANTED) != 0) {
  1810. -         wdc->sc_flags &= ~WDCF_WANTED;
  1811. -         wakeup(wdc);
  1812. -         return;
  1813. -     }
  1814. - loop:
  1815. -     /* Is there a drive for the controller to do a transfer with? */
  1816. -     wd = wdc->sc_drives.tqh_first;
  1817. -     if (wd == NULL)
  1818. -         return;
  1819. -     
  1820. -     /* Is there a transfer to this drive?  If not, deactivate drive. */
  1821. -     bp = wd->sc_q.b_actf;
  1822. -     
  1823. -     if (wdc->sc_errors >= WDIORETRIES) {
  1824. -         wderror(wd, bp, "hard error");
  1825. -         bp->b_error = EIO;
  1826. -         bp->b_flags |= B_ERROR;
  1827. -         wdfinish(wd, bp);
  1828. -         goto loop;
  1829. -     }
  1830. -     /* Do control operations specially. */
  1831. -     if (wd->sc_state < OPEN) {
  1832. -         /*
  1833. -          * Actually, we want to be careful not to mess with the control
  1834. -          * state if the device is currently busy, but we can assume
  1835. -          * that we never get to this point if that's the case.
  1836. -          */
  1837. -         if (wdcontrol(wd) == 0) {
  1838. -             /* The drive is busy.  Wait. */
  1839. -             return;
  1840. -         }
  1841. -     }
  1842. -     /*
  1843. -      * WDCF_ERROR is set by wdcunwedge() and wdcintr() when an error is
  1844. -      * encountered.  If we are in multi-sector mode, then we switch to
  1845. -      * single-sector mode and retry the operation from the start.
  1846. -      */
  1847. -     if (wdc->sc_flags & WDCF_ERROR) {
  1848. -         wdc->sc_flags &= ~WDCF_ERROR;
  1849. -         if ((wdc->sc_flags & WDCF_SINGLE) == 0) {
  1850. -             wdc->sc_flags |= WDCF_SINGLE;
  1851. -             wd->sc_skip = 0;
  1852. -         }
  1853. -     }
  1854. -     lp = wd->sc_dk.dk_label;
  1855. -     /* When starting a transfer... */
  1856. -     if (wd->sc_skip == 0) {
  1857. -         int part = WDPART(bp->b_dev);
  1858. -         daddr_t blkno;
  1859. - #ifdef WDDEBUG
  1860. -         printf("\n%s: wdcstart %s %d@%d; map ", wd->sc_dev.dv_xname,
  1861. -             (bp->b_flags & B_READ) ? "read" : "write", bp->b_bcount,
  1862. -             bp->b_blkno);
  1863. - #endif
  1864. -         wd->sc_bcount = bp->b_bcount;
  1865. -         blkno = bp->b_blkno;
  1866. -         if (part != RAW_PART)
  1867. -             blkno += lp->d_partitions[part].p_offset;
  1868. -         wd->sc_blkno = blkno / (lp->d_secsize / DEV_BSIZE);
  1869. -     } else {
  1870. - #ifdef WDDEBUG
  1871. -         printf(" %d)%x", wd->sc_skip, inb(wd->sc_iobase+wd_altsts));
  1872. - #endif
  1873. -     }
  1874. -     /* When starting a multi-sector transfer, or doing single-sector
  1875. -         transfers... */
  1876. -     if (wd->sc_skip == 0 || (wdc->sc_flags & WDCF_SINGLE) != 0 ||
  1877. -         wd->sc_mode == WDM_DMA) {
  1878. -         daddr_t blkno = wd->sc_blkno;
  1879. -         long cylin, head, sector;
  1880. -         int command;
  1881. -         if ((wdc->sc_flags & WDCF_SINGLE) != 0)
  1882. -             nblks = 1;
  1883. -         else if (wd->sc_mode != WDM_DMA)
  1884. -             nblks = wd->sc_bcount / lp->d_secsize;
  1885. -         else
  1886. -             nblks = min(wd->sc_bcount / lp->d_secsize, 8);
  1887. -         /* Check for bad sectors and adjust transfer, if necessary. */
  1888. -         if ((lp->d_flags & D_BADSECT) != 0
  1889. - #ifdef B_FORMAT
  1890. -             && (bp->b_flags & B_FORMAT) == 0
  1891. - #endif
  1892. -             ) {
  1893. -             long blkdiff;
  1894. -             int i;
  1895. -             for (i = 0; (blkdiff = wd->sc_badsect[i]) != -1; i++) {
  1896. -                 blkdiff -= blkno;
  1897. -                 if (blkdiff < 0)
  1898. -                     continue;
  1899. -                 if (blkdiff == 0) {
  1900. -                     /* Replace current block of transfer. */
  1901. -                     blkno =
  1902. -                         lp->d_secperunit - lp->d_nsectors - i - 1;
  1903. -                 }
  1904. -                 if (blkdiff < nblks) {
  1905. -                     /* Bad block inside transfer. */
  1906. -                     wdc->sc_flags |= WDCF_SINGLE;
  1907. -                     nblks = 1;
  1908. -                 }
  1909. -                 break;
  1910. -             }
  1911. -             /* Tranfer is okay now. */
  1912. -         }
  1913. -         if ((wd->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) {
  1914. -             sector = (blkno >> 0) & 0xff;
  1915. -             cylin = (blkno >> 8) & 0xffff;
  1916. -             head = (blkno >> 24) & 0xf;
  1917. -             head |= WDSD_LBA;
  1918. -         } else {
  1919. -             sector = blkno % lp->d_nsectors;
  1920. -             sector++;    /* Sectors begin with 1, not 0. */
  1921. -             blkno /= lp->d_nsectors;
  1922. -             head = blkno % lp->d_ntracks;
  1923. -             blkno /= lp->d_ntracks;
  1924. -             cylin = blkno;
  1925. -             head |= WDSD_CHS;
  1926. -         }
  1927. -         if (wd->sc_mode == WDM_PIOSINGLE ||
  1928. -             (wdc->sc_flags & WDCF_SINGLE) != 0)
  1929. -             wd->sc_nblks = 1;
  1930. -         else if (wd->sc_mode == WDM_PIOMULTI)
  1931. -             wd->sc_nblks = min(nblks, wd->sc_multiple);
  1932. -         else
  1933. -             wd->sc_nblks = nblks;
  1934. -         wd->sc_nbytes = wd->sc_nblks * lp->d_secsize;
  1935. -     
  1936. - #ifdef B_FORMAT
  1937. -         if (bp->b_flags & B_FORMAT) {
  1938. -             sector = lp->d_gap3;
  1939. -             nblks = lp->d_nsectors;
  1940. -             command = WDCC_FORMAT;
  1941. -         } else
  1942. - #endif
  1943. -         switch (wd->sc_mode) {
  1944. -         case WDM_DMA:
  1945. - #if 0
  1946. -             command = (bp->b_flags & B_READ) ?
  1947. -                 WDCC_READDMA : WDCC_WRITEDMA;
  1948. -             /* Start the DMA channel and bounce the buffer if
  1949. -                necessary. */
  1950. -             isa_dmastart(
  1951. -                 bp->b_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE,
  1952. -                 bp->b_data + wd->sc_skip,
  1953. -                 wd->sc_nbytes, wdc->sc_drq);
  1954. - #endif
  1955. -             panic("wd cannot do DMA yet\n");
  1956. -             break;
  1957. -         case WDM_PIOMULTI:
  1958. -             command = (bp->b_flags & B_READ) ?
  1959. -                 WDCC_READMULTI : WDCC_WRITEMULTI;
  1960. -             break;
  1961. -         case WDM_PIOSINGLE:
  1962. -             command = (bp->b_flags & B_READ) ?
  1963. -                 WDCC_READ : WDCC_WRITE;
  1964. -             break;
  1965. -         default:
  1966. - #ifdef DIAGNOSTIC
  1967. -             panic("bad wd mode");
  1968. - #endif
  1969. -             return;
  1970. -         }
  1971. -     
  1972. -         /* Initiate command! */
  1973. -         if (wdcommand(wd, command, cylin, head, sector, nblks) != 0) {
  1974. -             wderror(wd, NULL,
  1975. -                 "wdcstart: timeout waiting for unbusy");
  1976. -             wdcunwedge(wdc);
  1977. -             return;
  1978. -         }
  1979.   #ifdef WDDEBUG
  1980. !         printf("sector %d cylin %d head %d addr %x sts %x\n", sector,
  1981. !             cylin, head, bp->b_data, 0/*inb(wd->sc_iobase+wd_altsts*/));
  1982. ! #endif
  1983. !     } else if (wd->sc_nblks > 1) {
  1984. !         /* The number of blocks in the last stretch may be smaller. */
  1985. !         nblks = wd->sc_bcount / lp->d_secsize;
  1986. !         if (wd->sc_nblks > nblks) {
  1987. !             wd->sc_nblks = nblks;
  1988. !             wd->sc_nbytes = wd->sc_bcount;
  1989. !         }
  1990. !     }
  1991. !     /* If this was a write and not using DMA, push the data. */
  1992. !     if (wd->sc_mode != WDM_DMA &&
  1993. !         (bp->b_flags & (B_READ|B_WRITE)) == B_WRITE) {
  1994. !         if (wait_for_drq(wdc) < 0) {
  1995. !             wderror(wd, NULL, "wdcstart: timeout waiting for drq");
  1996. !             wdcunwedge(wdc);
  1997. !             return;
  1998. !         }
  1999. !         /* Push out data. */
  2000. !         if ((wd->sc_flags & WDF_32BIT) == 0)
  2001. !             outsw(wdc->sc_iobase+wd_data, bp->b_data + wd->sc_skip,
  2002. !                 wd->sc_nbytes >> 1);
  2003. !         else
  2004. !             outsl(wdc->sc_iobase+wd_data, bp->b_data + wd->sc_skip,
  2005. !                 wd->sc_nbytes >> 2);
  2006. !     }
  2007. !     wdc->sc_flags |= WDCF_ACTIVE;
  2008. !     timeout(wdctimeout, wdc, WAITTIME);
  2009. ! }
  2010. ! /*
  2011. !  * Interrupt routine for the controller.  Acknowledge the interrupt, check for
  2012. !  * errors on the current operation, mark it done if necessary, and start the
  2013. !  * next request.  Also check for a partially done transfer, and continue with
  2014. !  * the next chunk if so.
  2015. !  */
  2016. ! int
  2017. ! wdcintr(arg)
  2018. !     void *arg;
  2019. ! {
  2020. !     struct wdc_softc *wdc = arg;
  2021. !     struct wd_softc *wd;
  2022. !     struct buf *bp;
  2023. !     if ((wdc->sc_flags & WDCF_ACTIVE) == 0) {
  2024. !         /* Clear the pending interrupt and abort. */
  2025. !         (void) inb(wdc->sc_iobase+wd_status);
  2026. !         return 0;
  2027. !     }
  2028. !     wdc->sc_flags &= ~WDCF_ACTIVE;
  2029. !     untimeout(wdctimeout, wdc);
  2030. !     wd = wdc->sc_drives.tqh_first;
  2031. !     bp = wd->sc_q.b_actf;
  2032. ! #ifdef WDDEBUG
  2033. !     printf("I%d ", ctrlr);
  2034. ! #endif
  2035. !     if (wait_for_unbusy(wdc) < 0) {
  2036. !         wderror(wd, NULL, "wdcintr: timeout waiting for unbusy");
  2037. !         wdc->sc_status |= WDCS_ERR;    /* XXX */
  2038. !     }
  2039. !     
  2040. !     /* Is it not a transfer, but a control operation? */
  2041. !     if (wd->sc_state < OPEN) {
  2042. !         if (wdcontrol(wd) == 0) {
  2043. !             /* The drive is busy.  Wait. */
  2044. !             return 1;
  2045. !         }
  2046. !         wdcstart(wdc);
  2047. !         return 1;
  2048. !     }
  2049. !     /* Turn off the DMA channel and unbounce the buffer. */
  2050. !     if (wd->sc_mode == WDM_DMA)
  2051. !         panic("wd cannot do DMA\n");
  2052. ! #if 0
  2053. !         isa_dmadone(bp->b_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE,
  2054. !             bp->b_data + wd->sc_skip, wd->sc_nbytes, wdc->sc_drq);
  2055. ! #endif
  2056. !     /* Have we an error? */
  2057. !     if (wdc->sc_status & WDCS_ERR) {
  2058. ! #ifdef WDDEBUG
  2059. !         wderror(wd, NULL, "wdcintr");
  2060. ! #endif
  2061. !         if ((wdc->sc_flags & WDCF_SINGLE) == 0) {
  2062. !             wdc->sc_flags |= WDCF_ERROR;
  2063. !             goto restart;
  2064. !         }
  2065. ! #ifdef B_FORMAT
  2066. !         if (bp->b_flags & B_FORMAT)
  2067. !             goto bad;
  2068. ! #endif
  2069. !     
  2070. !         if (++wdc->sc_errors < WDIORETRIES)
  2071. !             goto restart;
  2072. !         wderror(wd, bp, "hard error");
  2073. ! #ifdef B_FORMAT
  2074. !     bad:
  2075.   #endif
  2076. -         bp->b_error = EIO;
  2077. -         bp->b_flags |= B_ERROR;
  2078. -         goto done;
  2079. -     }
  2080. -     /* If this was a read and not using DMA, fetch the data. */
  2081. -     if (wd->sc_mode != WDM_DMA &&
  2082. -         (bp->b_flags & (B_READ|B_WRITE)) == B_READ) {
  2083. -         if ((wdc->sc_status & (WDCS_DRDY | WDCS_DSC | WDCS_DRQ))
  2084. -             != (WDCS_DRDY | WDCS_DSC | WDCS_DRQ)) {
  2085. -             wderror(wd, NULL, "wdcintr: read intr before drq");
  2086. -             wdcunwedge(wdc);
  2087. -             return 1;
  2088. -         }
  2089. -         /* Pull in data. */
  2090. -         if ((wd->sc_flags & WDF_32BIT) == 0)
  2091. -             insw(wdc->sc_iobase+wd_data, bp->b_data + wd->sc_skip, 
  2092. -                 wd->sc_nbytes >> 1);
  2093. -         else
  2094. -             insl(wdc->sc_iobase+wd_data, bp->b_data + wd->sc_skip, 
  2095. -                 wd->sc_nbytes >> 2);
  2096. -     }
  2097. -     
  2098. -     /* If we encountered any abnormalities, flag it as a soft error. */
  2099. -     if (wdc->sc_errors > 0 ||
  2100. -         (wdc->sc_status & WDCS_CORR) != 0) {
  2101. -         wderror(wd, bp, "soft error (corrected)");
  2102. -         wdc->sc_errors = 0;
  2103. -     }
  2104. -     
  2105. -     /* Adjust pointers for the next block, if any. */
  2106. -     wd->sc_blkno += wd->sc_nblks;
  2107. -     wd->sc_skip += wd->sc_nbytes;
  2108. -     wd->sc_bcount -= wd->sc_nbytes;
  2109. -     /* See if this transfer is complete. */
  2110. -     if (wd->sc_bcount > 0)
  2111. -         goto restart;
  2112. - done:
  2113. -     /* Done with this transfer, with or without error. */
  2114. -     wdfinish(wd, bp);
  2115. - restart:
  2116. -     /* Start the next operation, if any. */
  2117. -     wdcstart(wdc);
  2118.   
  2119. !     return 1;
  2120.   }
  2121.   
  2122.   /*
  2123. --- 312,322 ----
  2124.       struct uio *uio;
  2125.       int flags;
  2126.   {
  2127.   #ifdef WDDEBUG
  2128. !     printf("wdwrite\n");
  2129.   #endif
  2130.   
  2131. !     return (physio(wdstrategy, NULL, dev, B_WRITE, minphys, uio));
  2132.   }
  2133.   
  2134.   /*
  2135. ***************
  2136. *** 888,904 ****
  2137.    * Several drivers do this; it should be abstracted and made MP-safe.
  2138.    */
  2139.   int
  2140. ! wdlock(wd)
  2141. !     struct wd_softc *wd;
  2142.   {
  2143.       int error;
  2144.   
  2145. !     while ((wd->sc_flags & WDF_LOCKED) != 0) {
  2146. !         wd->sc_flags |= WDF_WANTED;
  2147. !         if ((error = tsleep(wd, PRIBIO | PCATCH, "wdlck", 0)) != 0)
  2148.               return error;
  2149.       }
  2150. !     wd->sc_flags |= WDF_LOCKED;
  2151.       return 0;
  2152.   }
  2153.   
  2154. --- 326,351 ----
  2155.    * Several drivers do this; it should be abstracted and made MP-safe.
  2156.    */
  2157.   int
  2158. ! wdlock(d_link)
  2159. !     struct wd_link *d_link;
  2160.   {
  2161.       int error;
  2162. +     int s;
  2163.   
  2164. ! #ifdef WDDEBUG
  2165. !     printf("wdlock\n");
  2166. ! #endif
  2167. !     s=splbio();
  2168. !     while ((d_link->sc_flags & WDF_LOCKED) != 0) {
  2169. !         d_link->sc_flags |= WDF_WANTED;
  2170. !         if ((error = tsleep(d_link, PRIBIO | PCATCH, "wdlck", 0)) != 0) {
  2171. !             splx(s);
  2172.               return error;
  2173. +         }
  2174.       }
  2175. !     d_link->sc_flags |= WDF_LOCKED;
  2176. !     splx(s);
  2177.       return 0;
  2178.   }
  2179.   
  2180. ***************
  2181. *** 906,919 ****
  2182.    * Unlock and wake up any waiters.
  2183.    */
  2184.   void
  2185. ! wdunlock(wd)
  2186. !     struct wd_softc *wd;
  2187.   {
  2188.   
  2189. !     wd->sc_flags &= ~WDF_LOCKED;
  2190. !     if ((wd->sc_flags & WDF_WANTED) != 0) {
  2191. !         wd->sc_flags &= ~WDF_WANTED;
  2192. !         wakeup(wd);
  2193.       }
  2194.   }
  2195.   
  2196. --- 353,369 ----
  2197.    * Unlock and wake up any waiters.
  2198.    */
  2199.   void
  2200. ! wdunlock(d_link)
  2201. !     struct wd_link *d_link;
  2202.   {
  2203. + #ifdef WDDEBUG
  2204. +     printf("wdunlock\n");
  2205. + #endif
  2206.   
  2207. !     d_link->sc_flags &= ~WDF_LOCKED;
  2208. !     if ((d_link->sc_flags & WDF_WANTED) != 0) {
  2209. !         d_link->sc_flags &= ~WDF_WANTED;
  2210. !         wakeup(d_link);
  2211.       }
  2212.   }
  2213.   
  2214. ***************
  2215. *** 924,931 ****
  2216. --- 374,387 ----
  2217.       struct proc *p;
  2218.   {
  2219.       struct wd_softc *wd;
  2220. +     struct wd_link *d_link;
  2221.       int unit, part;
  2222.       int error;
  2223. + #ifdef WDDEBUG
  2224. +     printf("wdopen\n");
  2225. + #endif
  2226.       
  2227.       unit = WDUNIT(dev);
  2228.       if (unit >= wd_cd.cd_ndevs)
  2229. ***************
  2230. *** 934,957 ****
  2231.       if (wd == 0)
  2232.           return ENXIO;
  2233.       
  2234. !     if ((error = wdlock(wd)) != 0)
  2235.           return error;
  2236.       if (wd->sc_dk.dk_openmask != 0) {
  2237.           /*
  2238.            * If any partition is open, but the disk has been invalidated,
  2239.            * disallow further opens.
  2240.            */
  2241. !         if ((wd->sc_flags & WDF_LOADED) == 0) {
  2242.               error = EIO;
  2243.               goto bad3;
  2244.           }
  2245.       } else {
  2246. !         if ((wd->sc_flags & WDF_LOADED) == 0) {
  2247. !             wd->sc_flags |= WDF_LOADED;
  2248.   
  2249.               /* Load the physical device parameters. */
  2250. !             if (wd_get_parms(wd) != 0) {
  2251.                   error = ENXIO;
  2252.                   goto bad2;
  2253.               }
  2254. --- 390,413 ----
  2255.       if (wd == 0)
  2256.           return ENXIO;
  2257.       
  2258. !     d_link = wd->d_link;
  2259. !     if ((error = wdlock(d_link)) != 0)
  2260.           return error;
  2261.       if (wd->sc_dk.dk_openmask != 0) {
  2262.           /*
  2263.            * If any partition is open, but the disk has been invalidated,
  2264.            * disallow further opens.
  2265.            */
  2266. !         if ((d_link->sc_flags & WDF_LOADED) == 0) {
  2267.               error = EIO;
  2268.               goto bad3;
  2269.           }
  2270.       } else {
  2271. !         if ((d_link->sc_flags & WDF_LOADED) == 0) {
  2272. !             d_link->sc_flags |= WDF_LOADED;
  2273.   
  2274.               /* Load the physical device parameters. */
  2275. !             if (wdc_get_parms(d_link) != 0) {
  2276.                   error = ENXIO;
  2277.                   goto bad2;
  2278.               }
  2279. ***************
  2280. *** 982,999 ****
  2281.       }
  2282.       wd->sc_dk.dk_openmask = wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
  2283.   
  2284. !     wdunlock(wd);
  2285.       return 0;
  2286.   
  2287.   bad2:
  2288. !     wd->sc_flags &= ~WDF_LOADED;
  2289.   
  2290.   bad:
  2291.       if (wd->sc_dk.dk_openmask == 0) {
  2292.       }
  2293.   
  2294.   bad3:
  2295. !     wdunlock(wd);
  2296.       return error;
  2297.   }
  2298.   
  2299. --- 438,455 ----
  2300.       }
  2301.       wd->sc_dk.dk_openmask = wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
  2302.   
  2303. !     wdunlock(d_link);
  2304.       return 0;
  2305.   
  2306.   bad2:
  2307. !     d_link->sc_flags &= ~WDF_LOADED;
  2308.   
  2309.   bad:
  2310.       if (wd->sc_dk.dk_openmask == 0) {
  2311.       }
  2312.   
  2313.   bad3:
  2314. !     wdunlock(d_link);
  2315.       return error;
  2316.   }
  2317.   
  2318. ***************
  2319. *** 1007,1013 ****
  2320.       int part = WDPART(dev);
  2321.       int error;
  2322.       
  2323. !     if ((error = wdlock(wd)) != 0)
  2324.           return error;
  2325.   
  2326.       switch (fmt) {
  2327. --- 463,469 ----
  2328.       int part = WDPART(dev);
  2329.       int error;
  2330.       
  2331. !     if ((error = wdlock(wd->d_link)) != 0)
  2332.           return error;
  2333.   
  2334.       switch (fmt) {
  2335. ***************
  2336. *** 1024,1030 ****
  2337.           /* XXXX Must wait for I/O to complete! */
  2338.       }
  2339.   
  2340. !     wdunlock(wd);
  2341.       return 0;
  2342.   }
  2343.   
  2344. --- 480,486 ----
  2345.           /* XXXX Must wait for I/O to complete! */
  2346.       }
  2347.   
  2348. !     wdunlock(wd->d_link);
  2349.       return 0;
  2350.   }
  2351.   
  2352. ***************
  2353. *** 1036,1057 ****
  2354.       struct wd_softc *wd;
  2355.   {
  2356.       struct disklabel *lp = wd->sc_dk.dk_label;
  2357.       char *errstring;
  2358.   
  2359.       bzero(lp, sizeof(struct disklabel));
  2360.       bzero(wd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
  2361.   
  2362.       lp->d_secsize = DEV_BSIZE;
  2363. !     lp->d_ntracks = wd->sc_params.wdp_heads;
  2364. !     lp->d_nsectors = wd->sc_params.wdp_sectors;
  2365. !     lp->d_ncylinders = wd->sc_params.wdp_cylinders;
  2366.       lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
  2367.   
  2368.   #if 0
  2369.       strncpy(lp->d_typename, "ST506 disk", 16);
  2370.       lp->d_type = DTYPE_ST506;
  2371.   #endif
  2372. !     strncpy(lp->d_packname, wd->sc_params.wdp_model, 16);
  2373.       lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders;
  2374.       lp->d_rpm = 3600;
  2375.       lp->d_interleave = 1;
  2376. --- 492,518 ----
  2377.       struct wd_softc *wd;
  2378.   {
  2379.       struct disklabel *lp = wd->sc_dk.dk_label;
  2380. +     struct wd_link *d_link = wd->d_link;
  2381.       char *errstring;
  2382.   
  2383. + #ifdef WDDEBUG
  2384. +     printf("wdgetdisklabel\n");
  2385. + #endif
  2386.       bzero(lp, sizeof(struct disklabel));
  2387.       bzero(wd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
  2388.   
  2389.       lp->d_secsize = DEV_BSIZE;
  2390. !     lp->d_ntracks = d_link->sc_params.wdp_heads;
  2391. !     lp->d_nsectors = d_link->sc_params.wdp_sectors;
  2392. !     lp->d_ncylinders = d_link->sc_params.wdp_cylinders;
  2393.       lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
  2394.   
  2395.   #if 0
  2396.       strncpy(lp->d_typename, "ST506 disk", 16);
  2397.       lp->d_type = DTYPE_ST506;
  2398.   #endif
  2399. !     strncpy(lp->d_packname, d_link->sc_params.wdp_model, 16);
  2400.       lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders;
  2401.       lp->d_rpm = 3600;
  2402.       lp->d_interleave = 1;
  2403. ***************
  2404. *** 1067,1076 ****
  2405.       lp->d_magic2 = DISKMAGIC;
  2406.       lp->d_checksum = dkcksum(lp);
  2407.   
  2408. !     wd->sc_badsect[0] = -1;
  2409.   
  2410. !     if (wd->sc_state > RECAL)
  2411. !         wd->sc_state = RECAL;
  2412.       errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit, RAW_PART),
  2413.           wdstrategy, lp, wd->sc_dk.dk_cpulabel);
  2414.       if (errstring) {
  2415. --- 528,537 ----
  2416.       lp->d_magic2 = DISKMAGIC;
  2417.       lp->d_checksum = dkcksum(lp);
  2418.   
  2419. !     d_link->sc_badsect[0] = -1;
  2420.   
  2421. !     if (d_link->sc_state > RECAL)
  2422. !         d_link->sc_state = RECAL;
  2423.       errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit, RAW_PART),
  2424.           wdstrategy, lp, wd->sc_dk.dk_cpulabel);
  2425.       if (errstring) {
  2426. ***************
  2427. *** 1080,1087 ****
  2428.            * assume the DOS geometry is now in the label and try
  2429.            * again.  XXX This is a kluge.
  2430.            */
  2431. !         if (wd->sc_state > GEOMETRY)
  2432. !             wd->sc_state = GEOMETRY;
  2433.           errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit, RAW_PART),
  2434.               wdstrategy, lp, wd->sc_dk.dk_cpulabel);
  2435.       }
  2436. --- 541,548 ----
  2437.            * assume the DOS geometry is now in the label and try
  2438.            * again.  XXX This is a kluge.
  2439.            */
  2440. !         if (d_link->sc_state > GEOMETRY)
  2441. !             d_link->sc_state = GEOMETRY;
  2442.           errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit, RAW_PART),
  2443.               wdstrategy, lp, wd->sc_dk.dk_cpulabel);
  2444.       }
  2445. ***************
  2446. *** 1090,1359 ****
  2447.           return;
  2448.       }
  2449.   
  2450. !     if (wd->sc_state > GEOMETRY)
  2451. !         wd->sc_state = GEOMETRY;
  2452.       if ((lp->d_flags & D_BADSECT) != 0)
  2453.           bad144intern(wd);
  2454.   }
  2455.   
  2456. - /*
  2457. -  * Implement operations needed before read/write.
  2458. -  * Returns 0 if operation still in progress, 1 if completed.
  2459. -  */
  2460. - int
  2461. - wdcontrol(wd)
  2462. -     struct wd_softc *wd;
  2463. - {
  2464. -     struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
  2465. -     
  2466. -     switch (wd->sc_state) {
  2467. -     case RECAL:            /* Set SDH, step rate, do recal. */
  2468. -         if (wdcommandshort(wdc, wd->sc_drive, WDCC_RECAL) != 0) {
  2469. -             wderror(wd, NULL, "wdcontrol: recal failed (1)");
  2470. -             goto bad;
  2471. -         }
  2472. -         wd->sc_state = RECAL_WAIT;
  2473. -         break;
  2474. -     case RECAL_WAIT:
  2475. -         if (wdc->sc_status & WDCS_ERR) {
  2476. -             wderror(wd, NULL, "wdcontrol: recal failed (2)");
  2477. -             goto bad;
  2478. -         }
  2479. -         /* fall through */
  2480. -     case GEOMETRY:
  2481. -         if ((wd->sc_params.wdp_capabilities & WD_CAP_LBA) != 0)
  2482. -             goto multimode;
  2483. -         if (wdsetctlr(wd) != 0) {
  2484. -             /* Already printed a message. */
  2485. -             goto bad;
  2486. -         }
  2487. -         wd->sc_state = GEOMETRY_WAIT;
  2488. -         break;
  2489. -     case GEOMETRY_WAIT:
  2490. -         if (wdc->sc_status & WDCS_ERR) {
  2491. -             wderror(wd, NULL, "wdcontrol: geometry failed");
  2492. -             goto bad;
  2493. -         }
  2494. -         /* fall through */
  2495. -     case MULTIMODE:
  2496. -     multimode:
  2497. -         if (wd->sc_mode != WDM_PIOMULTI)
  2498. -             goto open;
  2499. -         outb(wdc->sc_iobase+wd_seccnt, wd->sc_multiple);
  2500. -         if (wdcommandshort(wdc, wd->sc_drive, WDCC_SETMULTI) != 0) {
  2501. -             wderror(wd, NULL, "wdcontrol: setmulti failed (1)");
  2502. -             goto bad;
  2503. -         }
  2504. -         wd->sc_state = MULTIMODE_WAIT;
  2505. -         break;
  2506. -     case MULTIMODE_WAIT:
  2507. -         if (wdc->sc_status & WDCS_ERR) {
  2508. -             wderror(wd, NULL, "wdcontrol: setmulti failed (2)");
  2509. -             goto bad;
  2510. -         }
  2511. -         /* fall through */
  2512. -     case OPEN:
  2513. -     open:
  2514. -         wdc->sc_errors = 0;
  2515. -         wd->sc_state = OPEN;
  2516. -         /*
  2517. -          * The rest of the initialization can be done by normal means.
  2518. -          */
  2519. -         return 1;
  2520. -     bad:
  2521. -         wdcunwedge(wdc);
  2522. -         return 0;
  2523. -     }
  2524. -     wdc->sc_flags |= WDCF_ACTIVE;
  2525. -     timeout(wdctimeout, wdc, WAITTIME);
  2526. -     return 0;
  2527. - }
  2528. - /*
  2529. -  * Wait for the drive to become ready and send a command.
  2530. -  * Return -1 if busy for too long or 0 otherwise.
  2531. -  * Assumes interrupts are blocked.
  2532. -  */
  2533. - int
  2534. - wdcommand(wd, command, cylin, head, sector, count)
  2535. -     struct wd_softc *wd;
  2536. -     int command;
  2537. -     int cylin, head, sector, count;
  2538. - {
  2539. -     struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
  2540. -     int iobase = wdc->sc_iobase;
  2541. -     int stat;
  2542. -     
  2543. -     /* Select drive, head, and addressing mode. */
  2544. -     outb(iobase+wd_sdh, WDSD_IBM | (wd->sc_drive << 4) | head);
  2545. -     /* Wait for it to become ready to accept a command. */
  2546. -     if (command == WDCC_IDP)
  2547. -         stat = wait_for_unbusy(wdc);
  2548. -     else
  2549. -         stat = wdcwait(wdc, WDCS_DRDY);
  2550. -     if (stat < 0)
  2551. -         return -1;
  2552. -     
  2553. -     /* Load parameters. */
  2554. -     if (wd->sc_dk.dk_label->d_type == DTYPE_ST506)
  2555. -         outb(iobase+wd_precomp, wd->sc_dk.dk_label->d_precompcyl / 4);
  2556. -     else
  2557. -         outb(iobase+wd_features, 0);
  2558. -     outb(iobase+wd_cyl_lo, cylin);
  2559. -     outb(iobase+wd_cyl_hi, cylin >> 8);
  2560. -     outb(iobase+wd_sector, sector);
  2561. -     outb(iobase+wd_seccnt, count);
  2562. -     /* Send command. */
  2563. -     outb(iobase+wd_command, command);
  2564. -     return 0;
  2565. - }
  2566. - /*
  2567. -  * Simplified version of wdcommand().
  2568. -  */
  2569. - int
  2570. - wdcommandshort(wdc, drive, command)
  2571. -     struct wdc_softc *wdc;
  2572. -     int drive;
  2573. -     int command;
  2574. - {
  2575. -     int iobase = wdc->sc_iobase;
  2576. -     /* Select drive. */
  2577. -     outb(iobase+wd_sdh, WDSD_IBM | (drive << 4));
  2578. -     if (wdcwait(wdc, WDCS_DRDY) < 0)
  2579. -         return -1;
  2580. -     outb(iobase+wd_command, command);
  2581. -     return 0;
  2582. - }
  2583.   
  2584.   /*
  2585.    * Tell the drive what geometry to use.
  2586.    */
  2587.   int
  2588. ! wdsetctlr(wd)
  2589. !     struct wd_softc *wd;
  2590.   {
  2591.   
  2592.   #ifdef WDDEBUG
  2593. !     printf("wd(%d,%d) C%dH%dS%d\n", wd->sc_dev.dv_unit, wd->sc_drive,
  2594.           wd->sc_dk.dk_label->d_ncylinders, wd->sc_dk.dk_label->d_ntracks,
  2595.           wd->sc_dk.dk_label->d_nsectors);
  2596.   #endif
  2597.       
  2598. !     if (wdcommand(wd, WDCC_IDP, wd->sc_dk.dk_label->d_ncylinders,
  2599. !         wd->sc_dk.dk_label->d_ntracks - 1, 0,
  2600. !         wd->sc_dk.dk_label->d_nsectors) != 0) {
  2601. !         wderror(wd, NULL, "wdsetctlr: geometry upload failed");
  2602.           return -1;
  2603.       }
  2604.   
  2605.       return 0;
  2606.   }
  2607.   
  2608. - /*
  2609. -  * Get the drive parameters, if ESDI or ATA, or create fake ones for ST506.
  2610. -  */
  2611.   int
  2612. ! wd_get_parms(wd)
  2613. !     struct wd_softc *wd;
  2614. ! {
  2615. !     struct wdc_softc *wdc = (void *)wd->sc_dev.dv_parent;
  2616. !     int i;
  2617. !     char tb[DEV_BSIZE];
  2618. !     int s, error;
  2619. !     /*
  2620. !      * XXX
  2621. !      * The locking done here, and the length of time this may keep the rest
  2622. !      * of the system suspended, is a kluge.  This should be rewritten to
  2623. !      * set up a transfer and queue it through wdstart(), but it's called
  2624. !      * infrequently enough that this isn't a pressing matter.
  2625. !      */
  2626. !     s = splbio();
  2627. !     while ((wdc->sc_flags & WDCF_ACTIVE) != 0) {
  2628. !         wdc->sc_flags |= WDCF_WANTED;
  2629. !         if ((error = tsleep(wdc, PRIBIO | PCATCH, "wdprm", 0)) != 0) {
  2630. !             splx(s);
  2631. !             return error;
  2632. !         }
  2633. !     }
  2634. !     if (wdcommandshort(wdc, wd->sc_drive, WDCC_IDENTIFY) != 0 ||
  2635. !         wait_for_drq(wdc) != 0) {
  2636. !         /*
  2637. !          * We `know' there's a drive here; just assume it's old.
  2638. !          * This geometry is only used to read the MBR and print a
  2639. !          * (false) attach message.
  2640. !          */
  2641. !         strncpy(wd->sc_dk.dk_label->d_typename, "ST506",
  2642. !             sizeof wd->sc_dk.dk_label->d_typename);
  2643. !         wd->sc_dk.dk_label->d_type = DTYPE_ST506;
  2644. !         strncpy(wd->sc_params.wdp_model, "unknown",
  2645. !             sizeof wd->sc_params.wdp_model);
  2646. !         wd->sc_params.wdp_config = WD_CFG_FIXED;
  2647. !         wd->sc_params.wdp_cylinders = 1024;
  2648. !         wd->sc_params.wdp_heads = 8;
  2649. !         wd->sc_params.wdp_sectors = 17;
  2650. !         wd->sc_params.wdp_maxmulti = 0;
  2651. !         wd->sc_params.wdp_usedmovsd = 0;
  2652. !         wd->sc_params.wdp_capabilities = 0;
  2653. !     } else {
  2654. !         strncpy(wd->sc_dk.dk_label->d_typename, "ESDI/IDE",
  2655. !             sizeof wd->sc_dk.dk_label->d_typename);
  2656. !         wd->sc_dk.dk_label->d_type = DTYPE_ESDI;
  2657. !         /* Read in parameter block. */
  2658. !         insw(wdc->sc_iobase+wd_data, tb, sizeof(tb) / sizeof(short));
  2659. !         bcopy(tb, &wd->sc_params, sizeof(struct wdparams));
  2660. !         /* Shuffle string byte order. */
  2661. !         for (i = 0; i < sizeof(wd->sc_params.wdp_model); i += 2) {
  2662. !             u_short *p;
  2663. !             p = (u_short *)(wd->sc_params.wdp_model + i);
  2664. !             *p = ntohs(*p);
  2665. !         }
  2666. !     }
  2667. !     /* Clear any leftover interrupt. */
  2668. !     (void) inb(wdc->sc_iobase+wd_status);
  2669. !     /* Restart the queue. */
  2670. !     wdcstart(wdc);
  2671. !     splx(s);
  2672. !     return 0;
  2673. ! }
  2674. ! int
  2675. ! wdioctl(dev, cmd, addr, flag, p)
  2676.       dev_t dev;
  2677. !     u_long cmd;
  2678.       caddr_t addr;
  2679.       int flag;
  2680.       struct proc *p;
  2681.   {
  2682.       struct wd_softc *wd = wd_cd.cd_devs[WDUNIT(dev)];
  2683.       int error;
  2684. !     
  2685. !     if ((wd->sc_flags & WDF_LOADED) == 0)
  2686.           return EIO;
  2687.   
  2688. !     switch (cmd) {
  2689.       case DIOCSBAD:
  2690.           if ((flag & FWRITE) == 0)
  2691.               return EBADF;
  2692. --- 551,607 ----
  2693.           return;
  2694.       }
  2695.   
  2696. !     if (d_link->sc_state > GEOMETRY)
  2697. !         d_link->sc_state = GEOMETRY;
  2698.       if ((lp->d_flags & D_BADSECT) != 0)
  2699.           bad144intern(wd);
  2700.   }
  2701.   
  2702.   
  2703.   /*
  2704.    * Tell the drive what geometry to use.
  2705.    */
  2706.   int
  2707. ! wdsetctlr(d_link)
  2708. !     struct wd_link *d_link;
  2709.   {
  2710. +     struct wd_softc *wd=(struct wd_softc *)d_link->wd_softc;
  2711.   
  2712.   #ifdef WDDEBUG
  2713. !     printf("wd(%d,%d) C%dH%dS%d\n", wd->sc_dev.dv_unit, d_link->sc_drive,
  2714.           wd->sc_dk.dk_label->d_ncylinders, wd->sc_dk.dk_label->d_ntracks,
  2715.           wd->sc_dk.dk_label->d_nsectors);
  2716.   #endif
  2717.       
  2718. !     if (wdccommand(d_link, WDCC_IDP, d_link->sc_drive, wd->sc_dk.dk_label->d_ncylinders,
  2719. !         wd->sc_dk.dk_label->d_ntracks - 1, 0, wd->sc_dk.dk_label->d_nsectors)
  2720. !         != 0) {
  2721. !         wderror(d_link, NULL, "wdsetctlr: geometry upload failed");
  2722.           return -1;
  2723.       }
  2724.   
  2725.       return 0;
  2726.   }
  2727.   
  2728.   int
  2729. ! wdioctl(dev, xfer, addr, flag, p)
  2730.       dev_t dev;
  2731. !     u_long xfer;
  2732.       caddr_t addr;
  2733.       int flag;
  2734.       struct proc *p;
  2735.   {
  2736.       struct wd_softc *wd = wd_cd.cd_devs[WDUNIT(dev)];
  2737. +     struct wd_link *d_link = wd->d_link;
  2738.       int error;
  2739. ! #ifdef WDDEBUG
  2740. !     printf("wdioctl\n");
  2741. ! #endif
  2742. !     if ((d_link->sc_flags & WDF_LOADED) == 0)
  2743.           return EIO;
  2744.   
  2745. !     switch (xfer) {
  2746.       case DIOCSBAD:
  2747.           if ((flag & FWRITE) == 0)
  2748.               return EBADF;
  2749. ***************
  2750. *** 1377,1409 ****
  2751.           if ((flag & FWRITE) == 0)
  2752.               return EBADF;
  2753.   
  2754. !         if ((error = wdlock(wd)) != 0)
  2755.               return error;
  2756. !         wd->sc_flags |= WDF_LABELLING;
  2757.   
  2758.           error = setdisklabel(wd->sc_dk.dk_label,
  2759.               (struct disklabel *)addr, /*wd->sc_dk.dk_openmask : */0,
  2760.               wd->sc_dk.dk_cpulabel);
  2761.           if (error == 0) {
  2762. !             if (wd->sc_state > GEOMETRY)
  2763. !                 wd->sc_state = GEOMETRY;
  2764. !             if (cmd == DIOCWDINFO)
  2765.                   error = writedisklabel(WDLABELDEV(dev),
  2766.                       wdstrategy, wd->sc_dk.dk_label,
  2767.                       wd->sc_dk.dk_cpulabel);
  2768.           }
  2769.   
  2770. !         wd->sc_flags &= ~WDF_LABELLING;
  2771. !         wdunlock(wd);
  2772.           return error;
  2773.       
  2774.       case DIOCWLABEL:
  2775.           if ((flag & FWRITE) == 0)
  2776.               return EBADF;
  2777.           if (*(int *)addr)
  2778. !             wd->sc_flags |= WDF_WLABEL;
  2779.           else
  2780. !             wd->sc_flags &= ~WDF_WLABEL;
  2781.           return 0;
  2782.       
  2783.   #ifdef notyet
  2784. --- 625,657 ----
  2785.           if ((flag & FWRITE) == 0)
  2786.               return EBADF;
  2787.   
  2788. !         if ((error = wdlock(wd->d_link)) != 0)
  2789.               return error;
  2790. !         d_link->sc_flags |= WDF_LABELLING;
  2791.   
  2792.           error = setdisklabel(wd->sc_dk.dk_label,
  2793.               (struct disklabel *)addr, /*wd->sc_dk.dk_openmask : */0,
  2794.               wd->sc_dk.dk_cpulabel);
  2795.           if (error == 0) {
  2796. !             if (d_link->sc_state > GEOMETRY)
  2797. !                 d_link->sc_state = GEOMETRY;
  2798. !             if (xfer == DIOCWDINFO)
  2799.                   error = writedisklabel(WDLABELDEV(dev),
  2800.                       wdstrategy, wd->sc_dk.dk_label,
  2801.                       wd->sc_dk.dk_cpulabel);
  2802.           }
  2803.   
  2804. !         d_link->sc_flags &= ~WDF_LABELLING;
  2805. !         wdunlock(d_link);
  2806.           return error;
  2807.       
  2808.       case DIOCWLABEL:
  2809.           if ((flag & FWRITE) == 0)
  2810.               return EBADF;
  2811.           if (*(int *)addr)
  2812. !             d_link->sc_flags |= WDF_WLABEL;
  2813.           else
  2814. !             d_link->sc_flags &= ~WDF_WLABEL;
  2815.           return 0;
  2816.       
  2817.   #ifdef notyet
  2818. ***************
  2819. *** 1433,1439 ****
  2820.           return error;
  2821.       }
  2822.   #endif
  2823.       default:
  2824.           return ENOTTY;
  2825.       }
  2826. --- 681,687 ----
  2827.           return error;
  2828.       }
  2829.   #endif
  2830. !     
  2831.       default:
  2832.           return ENOTTY;
  2833.       }
  2834. ***************
  2835. *** 1460,1466 ****
  2836.       struct wd_softc *wd;
  2837.       int part;
  2838.       int size;
  2839. !     
  2840.       if (wdopen(dev, 0, S_IFBLK, NULL) != 0)
  2841.           return -1;
  2842.       wd = wd_cd.cd_devs[WDUNIT(dev)];
  2843. --- 708,717 ----
  2844.       struct wd_softc *wd;
  2845.       int part;
  2846.       int size;
  2847. ! #ifdef WDDEBUG
  2848. !     printf("wdsize\n");
  2849. ! #endif
  2850.       if (wdopen(dev, 0, S_IFBLK, NULL) != 0)
  2851.           return -1;
  2852.       wd = wd_cd.cd_devs[WDUNIT(dev)];
  2853. ***************
  2854. *** 1476,1484 ****
  2855.   
  2856.   
  2857.   #ifndef __BDEVSW_DUMP_OLD_TYPE
  2858. - /* #define WD_DUMP_NOT_TRUSTED if you just want to watch */
  2859.   static int wddoingadump;
  2860. ! static int wddumprecalibrated;
  2861.   
  2862.   /*
  2863.    * Dump core after a system crash.
  2864. --- 727,734 ----
  2865.   
  2866.   
  2867.   #ifndef __BDEVSW_DUMP_OLD_TYPE
  2868.   static int wddoingadump;
  2869. ! /*static int wddumprecalibrated;*/
  2870.   
  2871.   /*
  2872.    * Dump core after a system crash.
  2873. ***************
  2874. *** 1491,1500 ****
  2875.           size_t size;
  2876.   {
  2877.       struct wd_softc *wd;    /* disk unit to do the I/O */
  2878. !     struct wdc_softc *wdc;    /* disk controller to do the I/O */
  2879.       struct disklabel *lp;    /* disk's disklabel */
  2880.       int    unit, part;
  2881.       int    nblks;        /* total number of sectors left to write */
  2882.   
  2883.       /* Check if recursive dump; if so, punt. */
  2884.       if (wddoingadump)
  2885. --- 741,751 ----
  2886.           size_t size;
  2887.   {
  2888.       struct wd_softc *wd;    /* disk unit to do the I/O */
  2889. !     struct wd_link *d_link; /* link struct for this disk */
  2890.       struct disklabel *lp;    /* disk's disklabel */
  2891.       int    unit, part;
  2892.       int    nblks;        /* total number of sectors left to write */
  2893. +     int err;
  2894.   
  2895.       /* Check if recursive dump; if so, punt. */
  2896.       if (wddoingadump)
  2897. ***************
  2898. *** 1505,1521 ****
  2899.       if (unit >= wd_cd.cd_ndevs)
  2900.           return ENXIO;
  2901.       wd = wd_cd.cd_devs[unit];
  2902.       if (wd == 0)
  2903.           return ENXIO;
  2904.   
  2905.       part = WDPART(dev);
  2906.   
  2907.       /* Make sure it was initialized. */
  2908. !     if (wd->sc_state < OPEN)
  2909.           return ENXIO;
  2910.   
  2911. -     wdc = (void *)wd->sc_dev.dv_parent;
  2912.           /* Convert to disk sectors.  Request must be a multiple of size. */
  2913.       lp = wd->sc_dk.dk_label;
  2914.       if ((size % lp->d_secsize) != 0)
  2915. --- 756,771 ----
  2916.       if (unit >= wd_cd.cd_ndevs)
  2917.           return ENXIO;
  2918.       wd = wd_cd.cd_devs[unit];
  2919. +     d_link = wd->d_link;
  2920.       if (wd == 0)
  2921.           return ENXIO;
  2922.   
  2923.       part = WDPART(dev);
  2924.   
  2925.       /* Make sure it was initialized. */
  2926. !     if (d_link->sc_state < OPEN)
  2927.           return ENXIO;
  2928.   
  2929.           /* Convert to disk sectors.  Request must be a multiple of size. */
  2930.       lp = wd->sc_dk.dk_label;
  2931.       if ((size % lp->d_secsize) != 0)
  2932. ***************
  2933. *** 1530,1614 ****
  2934.       /* Offset block number to start of partition. */
  2935.       blkno += lp->d_partitions[part].p_offset;
  2936.   
  2937. !     /* Recalibrate, if first dump transfer. */
  2938. !     if (wddumprecalibrated == 0) {
  2939. !         wddumprecalibrated = 1;
  2940. !         if (wdcommandshort(wdc, wd->sc_drive, WDCC_RECAL) != 0 ||
  2941. !             wait_for_ready(wdc) != 0 || wdsetctlr(wd) != 0 ||
  2942. !             wait_for_ready(wdc) != 0) {
  2943. !             wderror(wd, NULL, "wddump: recal failed");
  2944. !             return EIO;
  2945. !         }
  2946.       }
  2947. !    
  2948. !     while (nblks > 0) {
  2949. !         daddr_t xlt_blkno = blkno;
  2950. !         long cylin, head, sector;
  2951. !         if ((lp->d_flags & D_BADSECT) != 0) {
  2952. !             long blkdiff;
  2953. !             int i;
  2954. !             for (i = 0; (blkdiff = wd->sc_badsect[i]) != -1; i++) {
  2955. !                 blkdiff -= xlt_blkno;
  2956. !                 if (blkdiff < 0)
  2957. !                     continue;
  2958. !                 if (blkdiff == 0) {
  2959. !                     /* Replace current block of transfer. */
  2960. !                     xlt_blkno = lp->d_secperunit -
  2961. !                         lp->d_nsectors - i - 1;
  2962. !                 }
  2963. !                 break;
  2964. !             }
  2965. !             /* Tranfer is okay now. */
  2966. !         }
  2967. !         if ((wd->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) {
  2968. !             sector = (xlt_blkno >> 0) & 0xff;
  2969. !             cylin = (xlt_blkno >> 8) & 0xffff;
  2970. !             head = (xlt_blkno >> 24) & 0xf;
  2971. !             head |= WDSD_LBA;
  2972. !         } else {
  2973. !             sector = xlt_blkno % lp->d_nsectors;
  2974. !             sector++;    /* Sectors begin with 1, not 0. */
  2975. !             xlt_blkno /= lp->d_nsectors;
  2976. !             head = xlt_blkno % lp->d_ntracks;
  2977. !             xlt_blkno /= lp->d_ntracks;
  2978. !             cylin = xlt_blkno;
  2979. !             head |= WDSD_CHS;
  2980. !         }
  2981. ! #ifndef WD_DUMP_NOT_TRUSTED
  2982. !         if (wdcommand(wd, WDCC_WRITE, cylin, head, sector, 1) != 0 ||
  2983. !             wait_for_drq(wdc) != 0) {
  2984. !             wderror(wd, NULL, "wddump: write failed");
  2985. !             return EIO;
  2986. !         }
  2987. !     
  2988. !         outsw(wdc->sc_iobase+wd_data, va, lp->d_secsize >> 1);
  2989. !     
  2990. !         /* Check data request (should be done). */
  2991. !         if (wait_for_ready(wdc) != 0) {
  2992. !             wderror(wd, NULL, "wddump: timeout waiting for ready");
  2993. !             return EIO;
  2994. !         }
  2995. ! #else    /* WD_DUMP_NOT_TRUSTED */
  2996. !         /* Let's just talk about this first... */
  2997. !         printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
  2998. !             unit, va, cylin, head, sector);
  2999. !         delay(500 * 1000);    /* half a second */
  3000. ! #endif
  3001. !         /* update block count */
  3002. !         nblks -= 1;
  3003. !         blkno += 1;
  3004. !         va += lp->d_secsize;
  3005. !     }
  3006. !     wddoingadump = 0;
  3007. !     return 0;
  3008.   }
  3009.   #else /* __BDEVSW_DUMP_NEW_TYPE */
  3010.   int
  3011.   wddump(dev, blkno, va, size)
  3012.           dev_t dev;
  3013. --- 780,794 ----
  3014.       /* Offset block number to start of partition. */
  3015.       blkno += lp->d_partitions[part].p_offset;
  3016.   
  3017. !     err =  wdcdump(d_link, blkno, nblks, va);
  3018. !     if (err == 0) {
  3019. !         wddoingadump = 0;
  3020.       }
  3021. !     return err;
  3022.   }
  3023.   #else /* __BDEVSW_DUMP_NEW_TYPE */
  3024.   int
  3025.   wddump(dev, blkno, va, size)
  3026.           dev_t dev;
  3027. ***************
  3028. *** 1631,1789 ****
  3029.   {
  3030.       struct dkbad *bt = &wd->sc_dk.dk_cpulabel->bad;
  3031.       struct disklabel *lp = wd->sc_dk.dk_label;
  3032.       int i = 0;
  3033.   
  3034.       for (; i < 126; i++) {
  3035.           if (bt->bt_bad[i].bt_cyl == 0xffff)
  3036.               break;
  3037. !         wd->sc_badsect[i] =
  3038.               bt->bt_bad[i].bt_cyl * lp->d_secpercyl +
  3039.               (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors +
  3040.               (bt->bt_bad[i].bt_trksec & 0xff);
  3041.       }
  3042.       for (; i < 127; i++)
  3043. !         wd->sc_badsect[i] = -1;
  3044. ! }
  3045. ! int
  3046. ! wdcreset(wdc)
  3047. !     struct wdc_softc *wdc;
  3048. ! {
  3049. !     int iobase = wdc->sc_iobase;
  3050. !     /* Reset the device. */
  3051. !     if (wdresethack) {
  3052. !         outb(iobase+wd_ctlr, WDCTL_RST | WDCTL_IDS);
  3053. !         delay(1000);
  3054. !         outb(iobase+wd_ctlr, WDCTL_IDS);
  3055. !         delay(1000);
  3056. !         (void) inb(iobase+wd_error);
  3057. !         outb(iobase+wd_ctlr, WDCTL_4BIT);
  3058. !     }
  3059. !     if (wait_for_unbusy(wdc) < 0) {
  3060. !         printf("%s: reset failed\n", wdc->sc_dev.dv_xname);
  3061. !         return 1;
  3062. !     }
  3063. !     return 0;
  3064. ! }
  3065. ! void
  3066. ! wdcrestart(arg)
  3067. !     void *arg;
  3068. ! {
  3069. !     struct wdc_softc *wdc = arg;
  3070. !     int s;
  3071. !     s = splbio();
  3072. !     wdcstart(wdc);
  3073. !     splx(s);
  3074.   }
  3075.   
  3076. - /*
  3077. -  * Unwedge the controller after an unexpected error.  We do this by resetting
  3078. -  * it, marking all drives for recalibration, and stalling the queue for a short
  3079. -  * period to give the reset time to finish.
  3080. -  * NOTE: We use a timeout here, so this routine must not be called during
  3081. -  * autoconfig or dump.
  3082. -  */
  3083.   void
  3084. ! wdcunwedge(wdc)
  3085. !     struct wdc_softc *wdc;
  3086. ! {
  3087. !     int unit;
  3088. !     untimeout(wdctimeout, wdc);
  3089. !     (void) wdcreset(wdc);
  3090. !     /* Schedule recalibrate for all drives on this controller. */
  3091. !     for (unit = 0; unit < wd_cd.cd_ndevs; unit++) {
  3092. !         struct wd_softc *wd = wd_cd.cd_devs[unit];
  3093. !         if (!wd || (void *)wd->sc_dev.dv_parent != wdc)
  3094. !             continue;
  3095. !         if (wd->sc_state > RECAL)
  3096. !             wd->sc_state = RECAL;
  3097. !     }
  3098. !     wdc->sc_flags |= WDCF_ERROR;
  3099. !     ++wdc->sc_errors;
  3100. !     /* Wake up in a little bit and restart the operation. */
  3101. !     timeout(wdcrestart, wdc, RECOVERYTIME);
  3102. ! }
  3103. ! int
  3104. ! wdcwait(wdc, mask)
  3105. !     struct wdc_softc *wdc;
  3106. !     int mask;
  3107. ! {
  3108. !     int iobase = wdc->sc_iobase;
  3109. !     int timeout = 0;
  3110. !     u_char status;
  3111. ! #ifdef WDCNDELAY_DEBUG
  3112. !     extern int cold;
  3113. ! #endif
  3114. !     for (;;) {
  3115. !         wdc->sc_status = status = inb(iobase+wd_status);
  3116. !         if ((status & WDCS_BSY) == 0 && (status & mask) == mask)
  3117. !             break;
  3118. !         if (++timeout > WDCNDELAY)
  3119. !             return -1;
  3120. !         delay(WDCDELAY);
  3121. !     }
  3122. !     if (status & WDCS_ERR) {
  3123. !         wdc->sc_error = inb(iobase+wd_error);
  3124. !         return WDCS_ERR;
  3125. !     }
  3126. ! #ifdef WDCNDELAY_DEBUG
  3127. !     /* After autoconfig, there should be no long delays. */
  3128. !     if (!cold && timeout > WDCNDELAY_DEBUG)
  3129. !         printf("%s: warning: busy-wait took %dus\n",
  3130. !             wdc->sc_dev.dv_xname, WDCDELAY * timeout);
  3131. ! #endif
  3132. !     return 0;
  3133. ! }
  3134. ! void
  3135. ! wdctimeout(arg)
  3136. !     void *arg;
  3137. ! {
  3138. !     struct wdc_softc *wdc = (struct wdc_softc *)arg;
  3139. !     int s;
  3140. !     s = splbio();
  3141. !     if ((wdc->sc_flags & WDCF_ACTIVE) != 0) {
  3142. !         struct wd_softc *wd = wdc->sc_drives.tqh_first;
  3143. !         struct buf *bp = wd->sc_q.b_actf;
  3144. !         wdc->sc_flags &= ~WDCF_ACTIVE;
  3145. !         wderror(wdc, NULL, "lost interrupt");
  3146. !         printf("%s: lost interrupt: %sing %d@%s:%d (%d)\n",
  3147. !             wdc->sc_dev.dv_xname,
  3148. !             (bp->b_flags & B_READ) ? "read" : "writ",
  3149. !             wd->sc_nblks, wd->sc_dev.dv_xname, wd->sc_blkno, wd->sc_state);
  3150. !         wdcunwedge(wdc);
  3151. !     } else
  3152. !         wderror(wdc, NULL, "missing untimeout");
  3153. !     splx(s);
  3154. ! }
  3155. ! void
  3156. ! wderror(dev, bp, msg)
  3157. !     void *dev;
  3158.       struct buf *bp;
  3159.       char *msg;
  3160.   {
  3161. !     struct wd_softc *wd = dev;
  3162. !     struct wdc_softc *wdc = dev;
  3163.   
  3164.       if (bp) {
  3165. !         diskerr(bp, "wd", msg, LOG_PRINTF, wd->sc_skip / DEV_BSIZE,
  3166.               wd->sc_dk.dk_label);
  3167.           printf("\n");
  3168.       } else
  3169. !         printf("%s: %s: status %b error %b\n", wdc->sc_dev.dv_xname,
  3170. !             msg, wdc->sc_status, WDCS_BITS, wdc->sc_error, WDERR_BITS);
  3171.   }
  3172. --- 811,857 ----
  3173.   {
  3174.       struct dkbad *bt = &wd->sc_dk.dk_cpulabel->bad;
  3175.       struct disklabel *lp = wd->sc_dk.dk_label;
  3176. +     struct wd_link *d_link = wd->d_link;
  3177.       int i = 0;
  3178.   
  3179. + #ifdef WDDEBUG
  3180. +     printf("bad144intern\n");
  3181. + #endif
  3182.       for (; i < 126; i++) {
  3183.           if (bt->bt_bad[i].bt_cyl == 0xffff)
  3184.               break;
  3185. !         d_link->sc_badsect[i] =
  3186.               bt->bt_bad[i].bt_cyl * lp->d_secpercyl +
  3187.               (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors +
  3188.               (bt->bt_bad[i].bt_trksec & 0xff);
  3189.       }
  3190.       for (; i < 127; i++)
  3191. !         d_link->sc_badsect[i] = -1;
  3192.   }
  3193.   
  3194.   void
  3195. ! wderror(d_link, bp, msg)
  3196. !     struct wd_link *d_link;
  3197.       struct buf *bp;
  3198.       char *msg;
  3199.   {
  3200. !     struct wd_softc *wd = (struct wd_softc *)d_link->wd_softc;
  3201.   
  3202.       if (bp) {
  3203. !         diskerr(bp, "wd", msg, LOG_PRINTF, bp->b_bcount ,
  3204.               wd->sc_dk.dk_label);
  3205.           printf("\n");
  3206.       } else
  3207. !         printf("%s: %s\n", wd->sc_dev.dv_xname,
  3208. !             msg);
  3209. ! }
  3210. ! void
  3211. ! wddone(d_link, bp)
  3212. ! struct wd_link *d_link;
  3213. ! struct buf *bp;
  3214. ! {
  3215. !     struct wd_softc *wd = (void*)d_link->wd_softc;
  3216. !     disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid));
  3217.   }
  3218. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/mainbus/wdc.c sys/arch/arm32/mainbus/wdc.c
  3219. *** sys/arch/arm32.orig/mainbus/wdc.c    Thu Jan  1 01:00:00 1970
  3220. --- sys/arch/arm32/mainbus/wdc.c    Thu Jun 13 02:57:04 1996
  3221. ***************
  3222. *** 0 ****
  3223. --- 1,1747 ----
  3224. + /*    $NetBSD$    */
  3225. + /*
  3226. +  * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
  3227. +  *
  3228. +  * DMA and multi-sector PIO handling are derived from code contributed by
  3229. +  * Onno van der Linden.
  3230. +  *
  3231. +  * Atapi support added by Manuel Bouyer.
  3232. +  *
  3233. +  * Redistribution and use in source and binary forms, with or without
  3234. +  * modification, are permitted provided that the following conditions
  3235. +  * are met:
  3236. +  * 1. Redistributions of source code must retain the above copyright
  3237. +  *    notice, this list of conditions and the following disclaimer.
  3238. +  * 2. Redistributions in binary form must reproduce the above copyright
  3239. +  *    notice, this list of conditions and the following disclaimer in the
  3240. +  *    documentation and/or other materials provided with the distribution.
  3241. +  * 3. All advertising materials mentioning features or use of this software
  3242. +  *    must display the following acknowledgement:
  3243. +  *    This product includes software developed by Charles M. Hannum.
  3244. +  * 4. The name of the author may not be used to endorse or promote products
  3245. +  *    derived from this software without specific prior written permission.
  3246. +  *
  3247. +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  3248. +  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  3249. +  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  3250. +  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  3251. +  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  3252. +  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  3253. +  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  3254. +  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  3255. +  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  3256. +  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  3257. +  */
  3258. + #undef ATAPI_DEBUG_WDC
  3259. + #include <sys/param.h>
  3260. + #include <sys/systm.h>
  3261. + #include <sys/kernel.h>
  3262. + #include <sys/conf.h>
  3263. + #include <sys/file.h>
  3264. + #include <sys/stat.h>
  3265. + #include <sys/ioctl.h>
  3266. + #include <sys/buf.h>
  3267. + #include <sys/uio.h>
  3268. + #include <sys/malloc.h>
  3269. + #include <sys/device.h>
  3270. + #include <sys/disklabel.h>
  3271. + #include <sys/disk.h>
  3272. + #include <sys/syslog.h>
  3273. + #include <sys/proc.h>
  3274. + #include <vm/vm.h>
  3275. + #include <machine/cpu.h>
  3276. + #include <machine/irqhandler.h>
  3277. + #include <machine/io.h>
  3278. + #include <machine/katelib.h>
  3279. + #include <arm32/mainbus/mainbus.h>
  3280. + #include <arm32/mainbus/wdreg.h>
  3281. + #include <arm32/mainbus/wdlink.h>
  3282. + #include <atapi/atapilink.h>
  3283. + extern int wdresethack;
  3284. + #define    WAITTIME    (10 * hz)    /* time to wait for a completion */
  3285. +     /* this is a lot for hard drives, but not for cdroms */
  3286. + #define RECOVERYTIME hz/2
  3287. + #define WDCDELAY    100
  3288. + #define WDCNDELAY    100000        /* delay = 100us; so 10s for a controller state change */
  3289. + #if 0
  3290. + /* If you enable this, it will report any delays more than 100us * N long. */
  3291. + #define WDCNDELAY_DEBUG    50
  3292. + #endif
  3293. + #define    WDIORETRIES    5        /* number of retries before giving up */
  3294. + #define    WDPART(dev)            DISKPART(dev)
  3295. + LIST_HEAD(xfer_free_list, wdc_xfer) xfer_free_list;
  3296. + struct wdc_softc {
  3297. +     struct device sc_dev;
  3298. +     irqhandler_t sc_ih;
  3299. +     struct wd_link *d_link[2];
  3300. +     struct bus_link *ab_link;
  3301. +     struct wdc_link ctlr_link;
  3302. +     int sc_iobase;            /* I/O port base */
  3303. +     int sc_drq;            /* DMA channel */
  3304. +     TAILQ_HEAD(xferhead, wdc_xfer) sc_xfer;
  3305. +     int sc_flags;
  3306. + #define    WDCF_ACTIVE        0x01    /* controller is active */
  3307. + #define    WDCF_SINGLE        0x02    /* sector at a time mode */
  3308. + #define    WDCF_ERROR        0x04    /* processing a disk error */
  3309. + #define    WDCF_WANTED        0x08    /* XXX locking for wd_get_parms() */
  3310. + #define    WDCF_IRQ_WAIT        0x10    /* controller is waiting for irq */
  3311. + #define    WDCF_ONESLAVE        0x20    /* ctrl. has one ATAPI slave attached */
  3312. +     int sc_errors;            /* errors during current transfer */
  3313. +     u_char sc_status;        /* copy of status register */
  3314. +     u_char sc_error;        /* copy of error register */
  3315. + };
  3316. + int wdcprobe __P((struct device *, void *, void *));
  3317. + void wdcattach __P((struct device *, struct device *, void *));
  3318. + struct cfattach wdc_ca = {
  3319. +     sizeof(struct wdc_softc), wdcprobe, wdcattach
  3320. + };
  3321. + struct cfdriver wdc_cd = {
  3322. +       NULL, "wdc", DV_DULL
  3323. + };
  3324. + int wdcintr __P((void *));
  3325. + int wdc_ata_intr __P((struct wdc_softc *,struct wdc_xfer *));
  3326. + void wdcstart __P((struct wdc_softc *));
  3327. + void wdc_ata_start __P((struct wdc_softc *,struct wdc_xfer *));
  3328. + void wdc_atapi_start __P((struct wdc_softc *,struct wdc_xfer *));
  3329. + int wdcreset __P((struct wdc_softc *));
  3330. + void wdcrestart __P((void *arg));
  3331. + void wdcunwedge __P((struct wdc_softc *));
  3332. + void wdctimeout __P((void *arg));
  3333. + int wdcwait __P((struct wdc_softc *, int));
  3334. + int wdccontrol __P((struct wd_link *));
  3335. + void wdc_ata_done __P((struct wdc_softc *, struct wdc_xfer *));
  3336. + void wdc_free_xfer __P((struct wdc_xfer *));
  3337. + void wdcerror __P((struct wdc_softc*, char *));
  3338. + int wdccommandshort __P((struct wdc_softc *, int, int));
  3339. + void wdcbit_bucket __P(( struct wdc_softc *, int));
  3340. + int wdc_atapi_intr __P((struct wdc_softc *, struct wdc_xfer *));
  3341. + void wdc_atapi_done __P((struct wdc_softc *, struct wdc_xfer *));
  3342. + /* ST506 spec says that if READY or SEEKCMPLT go off, then the read or write
  3343. +    command is aborted. */
  3344. + #define    wait_for_drq(d)        wdcwait(d, WDCS_DRDY | WDCS_DSC | WDCS_DRQ)
  3345. + #define    wait_for_unbusy(d)      wdcwait(d, 0)
  3346. + #define    wait_for_ready(d)       wdcwait(d, WDCS_DRDY | WDCS_DSC)
  3347. + #define    atapi_ready(d)       wdcwait(d, WDCS_DRQ)
  3348. + #ifdef ATAPI_DEBUG
  3349. + static int wdc_nxfer;
  3350. + #endif
  3351. + int
  3352. + wdcprobe(parent, match, aux)
  3353. +     struct device *parent;
  3354. +     void *match, *aux;
  3355. + {
  3356. +     struct wdc_softc *wdc = match;
  3357. +     struct mainbus_attach_args *mb = aux;
  3358. +     int iobase;
  3359. +     wdc->sc_iobase = iobase = mb->mb_iobase;
  3360. +     /* Check if we have registers that work. */
  3361. +     outb(iobase+wd_error, 0x5a);    /* Error register not writable, */
  3362. +     outb(iobase+wd_cyl_lo, 0xa5);    /* but all of cyllo are. */
  3363. +     if (inb(iobase+wd_error) == 0x5a || inb(iobase+wd_cyl_lo) != 0xa5) {
  3364. +         /*
  3365. +          * Test for a controller with no IDE master, just one
  3366. +          * ATAPI device. Select drive 1, and try again.
  3367. +          */
  3368. +         outb(iobase+wd_sdh, WDSD_IBM | 0x10);
  3369. +         outb(iobase+wd_error, 0x5a);
  3370. +         outb(iobase+wd_cyl_lo, 0xa5);
  3371. +         if (inb(iobase+wd_error) == 0x5a || inb(iobase+wd_cyl_lo)
  3372. +             != 0xa5)
  3373. +             return 0;
  3374. +         wdc->sc_flags |= WDCF_ONESLAVE;
  3375. +     }
  3376. +     if (wdcreset(wdc) != 0) {
  3377. +         delay(500000);
  3378. +         if (wdcreset(wdc) != 0)
  3379. +             return 0;
  3380. +     }
  3381. +     /* Select drive 0 or ATAPI slave device */
  3382. +     if (wdc->sc_flags & WDCF_ONESLAVE)
  3383. +         outb(iobase+wd_sdh, WDSD_IBM | 0x10);
  3384. +     else
  3385. +         outb(iobase+wd_sdh, WDSD_IBM);
  3386. +     /* Wait for controller to become ready. */
  3387. +     if (wait_for_unbusy(wdc) < 0)
  3388. +         return 0;
  3389. +     
  3390. +     /* Start drive diagnostics. */
  3391. +     outb(iobase+wd_command, WDCC_DIAGNOSE);
  3392. +     /* Wait for command to complete. */
  3393. +     if (wait_for_unbusy(wdc) < 0)
  3394. +         return 0;
  3395. +     mb->mb_iosize = 32;
  3396. +     return 1;
  3397. + }
  3398. + int
  3399. + wdprint(aux, wdc)
  3400. +     void *aux;
  3401. +     char *wdc;
  3402. + {
  3403. +     struct wd_link *d_link = aux;
  3404. +     if (!wdc)
  3405. +         printf(" drive %d", d_link->sc_drive);
  3406. +     return QUIET;
  3407. + }
  3408. + void
  3409. + wdcattach(parent, self, aux)
  3410. +     struct device *parent, *self;
  3411. +     void *aux;
  3412. + {
  3413. +     struct wdc_softc *wdc = (void *)self;
  3414. +     struct mainbus_attach_args *mb = aux;
  3415. +     int drive;
  3416. +     TAILQ_INIT(&wdc->sc_xfer);
  3417. +     wdc->sc_drq = mb->mb_drq;
  3418. +     printf("\n");
  3419. +       wdc->sc_ih.ih_func = wdcintr;
  3420. +        wdc->sc_ih.ih_arg = wdc;
  3421. +        wdc->sc_ih.ih_level = IPL_BIO;
  3422. +        wdc->sc_ih.ih_name = "wdc";
  3423. +     if (irq_claim(mb->mb_irq, &wdc->sc_ih))
  3424. +         panic("Cannot claim IRQ %d for wdc%d\n", mb->mb_irq, parent->dv_unit);
  3425. +     wdc->ctlr_link.flags = 0;
  3426. + #ifdef ATAPI_DEBUG
  3427. +     wdc_nxfer = 0;
  3428. + #endif
  3429. +     for (drive = 0; drive < 2; drive++) {
  3430. +         wdc->sc_flags |= WDCF_ACTIVE; /* controller active while autoconf */
  3431. +         if (wdccommandshort(wdc, drive, WDCC_RECAL) != 0 ||
  3432. +                     wait_for_ready(wdc) != 0) {
  3433. +             wdc->d_link[drive]=NULL;
  3434. +             wdc->sc_flags &= ~WDCF_ACTIVE;
  3435. +         }
  3436. +         else {
  3437. +             wdc->sc_flags &= ~WDCF_ACTIVE;
  3438. +             wdc->d_link[drive]=malloc(sizeof(struct wd_link), M_DEVBUF, M_NOWAIT);
  3439. +             bzero(wdc->d_link[drive],sizeof(struct wd_link));
  3440. +             wdc->d_link[drive]->type = DRIVE;
  3441. +             wdc->d_link[drive]->wdc_softc =(caddr_t) wdc;
  3442. +             wdc->d_link[drive]->ctlr_link = &(wdc->ctlr_link);
  3443. +             wdc->d_link[drive]->sc_drive = drive;
  3444. +             if (wdc->sc_drq != DRQUNK) 
  3445. +                 wdc->d_link[drive]->sc_mode = WDM_DMA;
  3446. +             else wdc->d_link[drive]->sc_mode = 0;
  3447. +             (void)config_found(self, (void *)wdc->d_link[drive], wdprint);
  3448. +         }
  3449. +     }
  3450. +     wdc->ab_link = malloc(sizeof(struct bus_link), M_DEVBUF, M_NOWAIT);
  3451. +     bzero(wdc->ab_link,sizeof(struct bus_link));
  3452. +     wdc->ab_link->type = BUS;
  3453. +     wdc->ab_link->wdc_softc = (caddr_t) wdc;
  3454. +     wdc->ab_link->ctlr_link = &(wdc->ctlr_link);
  3455. +     wdc->ab_link->ctrl = self->dv_unit;
  3456. +     (void)config_found(self, (void *)wdc->ab_link, NULL);
  3457. + }
  3458. + /*
  3459. +  * Start I/O on a controller.  This does the calculation, and starts a read or
  3460. +  * write operation.  Called to from wdstart() to start a transfer, from
  3461. +  * wdcintr() to continue a multi-sector transfer or start the next transfer, or
  3462. +  * wdcrestart() after recovering from an error.
  3463. +  */
  3464. + void
  3465. + wdcstart(wdc)
  3466. +     struct wdc_softc *wdc;
  3467. + {
  3468. +     struct wdc_xfer *xfer;
  3469. +     if ((wdc->sc_flags & WDCF_ACTIVE) != 0 ) {
  3470. + #ifdef WDDEBUG
  3471. +         printf("wdcstart: already active\n");
  3472. + #endif
  3473. +         return; /* controller aleady active */
  3474. +     }
  3475. + #ifdef DIAGNOSTIC
  3476. +     if ((wdc->sc_flags & WDCF_IRQ_WAIT) != 0)
  3477. +         panic("wdcstart: controller waiting for irq\n");
  3478. + #endif
  3479. +     /*
  3480. +      * XXX
  3481. +      * This is a kluge.  See comments in wd_get_parms().
  3482. +      */
  3483. +     if ((wdc->sc_flags & WDCF_WANTED) != 0) {
  3484. + #ifdef ATAPI_DEBUG_WDC
  3485. +         printf("WDCF_WANTED\n");
  3486. + #endif
  3487. +         wdc->sc_flags &= ~WDCF_WANTED;
  3488. +         wakeup(wdc);
  3489. +         return;
  3490. +     }
  3491. +     /* is there a xfer ? */
  3492. +     xfer = wdc->sc_xfer.tqh_first;
  3493. +     if (xfer == NULL) {
  3494. + #ifdef ATAPI_DEBUG2
  3495. +         printf("wdcstart: null xfer\n");
  3496. + #endif
  3497. +         return;
  3498. +     }
  3499. +     wdc->sc_flags |= WDCF_ACTIVE;
  3500. +     if (xfer->c_flags & C_ATAPI) {
  3501. + #ifdef ATAPI_DEBUG_WDC
  3502. +         printf("wdcstart: atapi\n");
  3503. + #endif
  3504. +         wdc_atapi_start(wdc,xfer);
  3505. +     } else {
  3506. +         wdc_ata_start(wdc,xfer);
  3507. +     }
  3508. + }
  3509. + void wdc_ata_start(wdc, xfer)
  3510. +     struct wdc_softc *wdc;
  3511. +     struct wdc_xfer *xfer;
  3512. + {
  3513. +     struct wd_link *d_link;
  3514. +     struct buf *bp = xfer->c_bp;
  3515. +     int nblks;
  3516. +     d_link=xfer->d_link;
  3517. + /*loop:*/
  3518. +     
  3519. +     if (wdc->sc_errors >= WDIORETRIES) {
  3520. +         wderror(d_link, bp, "hard error");
  3521. +         xfer->c_flags |= C_ERROR;
  3522. +         wdc_ata_done(wdc, xfer);
  3523. +         return;
  3524. +     }
  3525. +     /* Do control operations specially. */
  3526. +     if (d_link->sc_state < OPEN) {
  3527. +         /*
  3528. +          * Actually, we want to be careful not to mess with the control
  3529. +          * state if the device is currently busy, but we can assume
  3530. +          * that we never get to this point if that's the case.
  3531. +          */
  3532. +         if (wdccontrol(d_link) == 0) {
  3533. +             /* The drive is busy.  Wait. */
  3534. +             return;
  3535. +         }
  3536. +     }
  3537. +     /*
  3538. +      * WDCF_ERROR is set by wdcunwedge() and wdcintr() when an error is
  3539. +      * encountered.  If we are in multi-sector mode, then we switch to
  3540. +      * single-sector mode and retry the operation from the start.
  3541. +      */
  3542. +     if (wdc->sc_flags & WDCF_ERROR) {
  3543. +         wdc->sc_flags &= ~WDCF_ERROR;
  3544. +         if ((wdc->sc_flags & WDCF_SINGLE) == 0) {
  3545. +             wdc->sc_flags |= WDCF_SINGLE;
  3546. +             xfer->c_skip = 0;
  3547. +         }
  3548. +     }
  3549. +     /* When starting a transfer... */
  3550. +     if (xfer->c_skip == 0) {
  3551. +         daddr_t blkno;
  3552. + #ifdef WDDEBUG
  3553. +         printf("\n%s: wdc_ata_start %s %d@%d; map ", wdc->sc_dev.dv_xname,
  3554. +             (xfer->c_flags & B_READ) ? "read" : "write", xfer->c_bcount,
  3555. +             xfer->c_blkno);
  3556. + #endif
  3557. +         blkno = xfer->c_blkno+xfer->c_p_offset;
  3558. +         xfer->c_blkno = blkno / (d_link->sc_lp->d_secsize / DEV_BSIZE);
  3559. +     } else {
  3560. + #ifdef WDDEBUG
  3561. +         printf(" %d)%x", xfer->c_skip, inb(wdc->sc_iobase+wd_altsts));
  3562. + #endif
  3563. +     }
  3564. +     /* When starting a multi-sector transfer, or doing single-sector
  3565. +         transfers... */
  3566. +     if (xfer->c_skip == 0 || (wdc->sc_flags & WDCF_SINGLE) != 0 ||
  3567. +         d_link->sc_mode == WDM_DMA) {
  3568. +         daddr_t blkno = xfer->c_blkno;
  3569. +         long cylin, head, sector;
  3570. +         int command;
  3571. +         if ((wdc->sc_flags & WDCF_SINGLE) != 0)
  3572. +             nblks = 1;
  3573. +         else if (d_link->sc_mode != WDM_DMA)
  3574. +             nblks = xfer->c_bcount / d_link->sc_lp->d_secsize;
  3575. +         else
  3576. +             nblks = min(xfer->c_bcount / d_link->sc_lp->d_secsize, 8);
  3577. +         /* Check for bad sectors and adjust transfer, if necessary. */
  3578. +         if ((d_link->sc_lp->d_flags & D_BADSECT) != 0
  3579. + #ifdef B_FORMAT
  3580. +             && (bp->b_flags & B_FORMAT) == 0
  3581. + #endif
  3582. +             ) {
  3583. +             long blkdiff;
  3584. +             int i;
  3585. +             for (i = 0; (blkdiff = d_link->sc_badsect[i]) != -1; i++) {
  3586. +                 blkdiff -= blkno;
  3587. +                 if (blkdiff < 0)
  3588. +                     continue;
  3589. +                 if (blkdiff == 0) {
  3590. +                     /* Replace current block of transfer. */
  3591. +                     blkno =
  3592. +                         d_link->sc_lp->d_secperunit -
  3593. +                         d_link->sc_lp->d_nsectors - i - 1;
  3594. +                 }
  3595. +                 if (blkdiff < nblks) {
  3596. +                     /* Bad block inside transfer. */
  3597. +                     wdc->sc_flags |= WDCF_SINGLE;
  3598. +                     nblks = 1;
  3599. +                 }
  3600. +                 break;
  3601. +             }
  3602. +             /* Tranfer is okay now. */
  3603. +         }
  3604. +         if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) {
  3605. +             sector = (blkno >> 0) & 0xff;
  3606. +             cylin = (blkno >> 8) & 0xffff;
  3607. +             head = (blkno >> 24) & 0xf;
  3608. +             head |= WDSD_LBA;
  3609. +         } else {
  3610. +             sector = blkno % d_link->sc_lp->d_nsectors;
  3611. +             sector++;    /* Sectors begin with 1, not 0. */
  3612. +             blkno /= d_link->sc_lp->d_nsectors;
  3613. +             head = blkno % d_link->sc_lp->d_ntracks;
  3614. +             blkno /= d_link->sc_lp->d_ntracks;
  3615. +             cylin = blkno;
  3616. +             head |= WDSD_CHS;
  3617. +         }
  3618. +         if (d_link->sc_mode == WDM_PIOSINGLE ||
  3619. +             (wdc->sc_flags & WDCF_SINGLE) != 0)
  3620. +             xfer->c_nblks = 1;
  3621. +         else if (d_link->sc_mode == WDM_PIOMULTI)
  3622. +             xfer->c_nblks = min(nblks, d_link->sc_multiple);
  3623. +         else
  3624. +             xfer->c_nblks = nblks;
  3625. +         xfer->c_nbytes = xfer->c_nblks * d_link->sc_lp->d_secsize;
  3626. +     
  3627. + #ifdef B_FORMAT
  3628. +         if (bp->b_flags & B_FORMAT) {
  3629. +             sector = d_link->sc_lp->d_gap3;
  3630. +             nblks = d_link->sc_lp->d_nsectors;
  3631. +             command = WDCC_FORMAT;
  3632. +         } else
  3633. + #endif
  3634. +         switch (d_link->sc_mode) {
  3635. +         case WDM_DMA:
  3636. +             panic("wdc: Cannot do DMA\n");
  3637. + #if 0
  3638. +             command = (xfer->c_flags & B_READ) ?
  3639. +                 WDCC_READDMA : WDCC_WRITEDMA;
  3640. +             /* Start the DMA channel and bounce the buffer if
  3641. +                necessary. */
  3642. +             isa_dmastart(xfer->c_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE,
  3643. +                 xfer->databuf + xfer->c_skip,
  3644. +                 xfer->c_nbytes, wdc->sc_drq);
  3645. +             break;
  3646. + #endif
  3647. +         case WDM_PIOMULTI:
  3648. +             command = (xfer->c_flags & B_READ) ?
  3649. +                 WDCC_READMULTI : WDCC_WRITEMULTI;
  3650. +             break;
  3651. +         case WDM_PIOSINGLE:
  3652. +             command = (xfer->c_flags & B_READ) ?
  3653. +                 WDCC_READ : WDCC_WRITE;
  3654. +             break;
  3655. +                 default:
  3656. + #ifdef DIAGNOSTIC
  3657. +                         panic("bad wd mode");
  3658. + #endif
  3659. +                         return;
  3660. +         }
  3661. +     
  3662. +         /* Initiate command! */
  3663. +         if (wdccommand(d_link, command, d_link->sc_drive, cylin, head, sector, nblks) != 0) {
  3664. +             wderror(d_link, NULL,
  3665. +                 "wdc_ata_start: timeout waiting for unbusy");
  3666. +             wdcunwedge(wdc);
  3667. +             return;
  3668. +         }
  3669. + #ifdef WDDEBUG
  3670. +         printf("sector %d cylin %d head %d addr %x sts %x\n", sector,
  3671. +             cylin, head, xfer->databuf, 0/*inb(wdc->sc_iobase+wd_altsts)*/);
  3672. + #endif
  3673. +     } else if (xfer->c_nblks > 1) {
  3674. +         /* The number of blocks in the last stretch may be smaller. */
  3675. +         nblks = xfer->c_bcount / d_link->sc_lp->d_secsize;
  3676. +         if (xfer->c_nblks > nblks) {
  3677. +             xfer->c_nblks = nblks;
  3678. +             xfer->c_nbytes = xfer->c_bcount;
  3679. +         }
  3680. +     }
  3681. +     /* If this was a write and not using DMA, push the data. */
  3682. +     if (d_link->sc_mode != WDM_DMA &&
  3683. +         (xfer->c_flags & (B_READ|B_WRITE)) == B_WRITE) {
  3684. +         if (wait_for_drq(wdc) < 0) {
  3685. +             wderror(d_link, NULL, "wdc_ata_start: timeout waiting for drq");
  3686. +             wdcunwedge(wdc);
  3687. +             return;
  3688. +         }
  3689. +         /* Push out data. */
  3690. +         if ((d_link->sc_flags & WDF_32BIT) == 0)
  3691. +             outsw(wdc->sc_iobase+wd_data, xfer->databuf + xfer->c_skip,
  3692. +                 xfer->c_nbytes >> 1);
  3693. +         else
  3694. +             outsl(wdc->sc_iobase+wd_data, xfer->databuf + xfer->c_skip,
  3695. +                 xfer->c_nbytes >> 2);
  3696. +     }
  3697. +     wdc->sc_flags |= WDCF_IRQ_WAIT;
  3698. + #ifdef WDDEBUG
  3699. +     printf("wdc_ata_start: timeout ");
  3700. + #endif
  3701. +     timeout(wdctimeout, wdc, WAITTIME);
  3702. + #ifdef WDDEBUG
  3703. +     printf("done\n");
  3704. + #endif
  3705. + }
  3706. + void
  3707. + wdc_atapi_start (wdc, xfer)
  3708. + struct wdc_softc *wdc;
  3709. + struct wdc_xfer *xfer;
  3710. + {
  3711. +     struct atapi_command_packet *acp = xfer->atapi_cmd;
  3712. + #ifdef ATAPI_DEBUG_WDC
  3713. +     printf("wdc_atapi_start, acp flags %lx\n",acp->flags);
  3714. + #endif
  3715. +     if (wdc->sc_errors >= WDIORETRIES) {
  3716. +         acp->status |= ERROR;
  3717. +         acp->error = inb (wdc->sc_iobase + wd_error);
  3718. +         wdc_atapi_done(wdc, xfer);
  3719. +         return;
  3720. +     }
  3721. +     if (wait_for_unbusy (wdc) != 0)
  3722. +         if (!(wdc->sc_status & WDCS_ERR)) {
  3723. +             printf ("wdc_atapi_start: not ready, st = %02x\n",wdc->sc_status);
  3724. +             acp->status = ERROR;
  3725. +             return;
  3726. +         }
  3727. +     if (wdccommand ((struct wd_link*)xfer->d_link, ATAPI_PACKET_COMMAND,
  3728. +         acp->drive, acp->data_size, 0, 0, 0) != 0) {
  3729. +         printf("wdc_atapi_start: can't send atapi paket command\n");
  3730. +         acp->status = ERROR;
  3731. +         wdc->sc_flags |= WDCF_IRQ_WAIT;
  3732. +         return;
  3733. +     }
  3734. +     if ((acp->flags & 0x0300) != ACAP_DRQ_INTR) {
  3735. +         int i, phase;
  3736. +         for (i=20000; i>0; --i) {
  3737. +             phase = (inb(wdc->sc_iobase + wd_ireason) & (WDCI_CMD | WDCI_IN)) |
  3738. +                 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
  3739. +             if (phase == PHASE_CMDOUT)
  3740. +                 break;
  3741. +             delay(10);
  3742. +         }
  3743. +         if (phase != PHASE_CMDOUT ) {
  3744. +             printf("wdc_atapi_start: timout waiting PHASE_CMDOUT");
  3745. +             acp->status = ERROR;
  3746. +             wdc_atapi_done(wdc, xfer);
  3747. +             return;
  3748. +         }
  3749. +         outsw (wdc->sc_iobase + wd_data, acp->command,
  3750. +             acp->command_size/ sizeof (short));
  3751. +     }
  3752. +     wdc->sc_flags |= WDCF_IRQ_WAIT;
  3753. +      
  3754. + #ifdef ATAPI_DEBUG2
  3755. +     printf("wdc_atapi_start: timeout\n");
  3756. + #endif
  3757. +     timeout(wdctimeout, wdc, WAITTIME);
  3758. +     return;
  3759. + }
  3760. + /*
  3761. +  * Interrupt routine for the controller.  Acknowledge the interrupt, check for
  3762. +  * errors on the current operation, mark it done if necessary, and start the
  3763. +  * next request.  Also check for a partially done transfer, and continue with
  3764. +  * the next chunk if so.
  3765. +  */
  3766. + int
  3767. + wdcintr(arg)
  3768. +     void *arg;
  3769. + {
  3770. +     struct wdc_softc *wdc = arg;
  3771. +     struct wdc_xfer *xfer;
  3772. +     if ((wdc->sc_flags & WDCF_IRQ_WAIT) == 0) {
  3773. +         /* Clear the pending interrupt and abort. */
  3774. +         u_char s = inb(wdc->sc_iobase+wd_status);
  3775. +         u_char e = inb(wdc->sc_iobase+wd_error);
  3776. +         u_char i = inb(wdc->sc_iobase+wd_seccnt);
  3777. + #ifdef ATAPI_DEBUG_WDC
  3778. +         printf ("wdcintr: inactive controller, punting st=%02x er=%02x irr=%02x\n", s, e, i);
  3779. + #endif /* ATAPI_DEBUG */
  3780. +        if (s & WDCS_DRQ) {
  3781. +             int len = inb (wdc->sc_iobase + wd_cyl_lo) +
  3782. +             256 * inb (wdc->sc_iobase + wd_cyl_hi);
  3783. + #ifdef ATAPI_DEBUG_WDC
  3784. +             printf ("wdcintr: clearing up %d bytes\n", len);
  3785. + #endif /* ATAPI_DEBUG */
  3786. +             wdcbit_bucket (wdc, len);
  3787. +         }
  3788. +         return 0;
  3789. +     }
  3790. + #ifdef WDDEBUG
  3791. +     printf("wdcintr\n");
  3792. + #endif
  3793. +     wdc->sc_flags &= ~WDCF_IRQ_WAIT;
  3794. +     xfer = wdc->sc_xfer.tqh_first;
  3795. +     if (xfer->c_flags & C_ATAPI) {
  3796. +         (void) wdc_atapi_intr(wdc,xfer);
  3797. +         return 0;
  3798. +     } else {
  3799. +         return wdc_ata_intr(wdc,xfer);
  3800. +     }
  3801. + }
  3802. + int
  3803. + wdc_ata_intr(wdc,xfer)
  3804. +     struct wdc_softc *wdc;
  3805. +     struct wdc_xfer *xfer;
  3806. + {
  3807. +     struct wd_link *d_link;
  3808. +     d_link = xfer->d_link;
  3809. +     if (wait_for_unbusy(wdc) < 0) {
  3810. +         wdcerror(wdc, "wdcintr: timeout waiting for unbusy");
  3811. +         wdc->sc_status |= WDCS_ERR;    /* XXX */
  3812. +     }
  3813. +     untimeout(wdctimeout, wdc);
  3814. +     /* Is it not a transfer, but a control operation? */
  3815. +     if (d_link->sc_state < OPEN) {
  3816. +         if (wdccontrol(d_link) == 0) {
  3817. +             /* The drive is busy.  Wait. */
  3818. +             return 1;
  3819. +         }
  3820. + #ifdef WDDEBUG
  3821. +         printf("wdc_ata_start from wdc_ata_intr(open) flags %d\n",
  3822. +             dc->sc_flags);
  3823. + #endif
  3824. +         wdc_ata_start(wdc,xfer);
  3825. +         return 1;
  3826. +     }
  3827. +     /* Turn off the DMA channel and unbounce the buffer. */
  3828. +     if (d_link->sc_mode == WDM_DMA)
  3829. +         panic("wdc: Cannot do DMA\n");
  3830. + #if 0
  3831. +         isa_dmadone(xfer->c_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE,
  3832. +             xfer->databuf + xfer->c_skip, xfer->c_nbytes, wdc->sc_drq);
  3833. + #endif
  3834. +     /* Have we an error? */
  3835. +     if (wdc->sc_status & WDCS_ERR) {
  3836. + #ifdef WDDEBUG
  3837. +         wderror(d_link, NULL, "wdc_ata_start");
  3838. + #endif
  3839. +         if ((wdc->sc_flags & WDCF_SINGLE) == 0) {
  3840. +             wdc->sc_flags |= WDCF_ERROR;
  3841. +             goto restart;
  3842. +         }
  3843. + #ifdef B_FORMAT
  3844. +         if (bp->b_flags & B_FORMAT)
  3845. +             goto bad;
  3846. + #endif
  3847. +     
  3848. +         if (++wdc->sc_errors < WDIORETRIES)
  3849. +             goto restart;
  3850. +         wderror(d_link, xfer->c_bp, "hard error");
  3851. + #ifdef B_FORMAT
  3852. +     bad:
  3853. + #endif
  3854. +         xfer->c_flags |= C_ERROR;
  3855. +         goto done;
  3856. +     }
  3857. +     /* If this was a read and not using DMA, fetch the data. */
  3858. +     if (d_link->sc_mode != WDM_DMA &&
  3859. +         (xfer->c_flags & (B_READ|B_WRITE)) == B_READ) {
  3860. +         if ((wdc->sc_status & (WDCS_DRDY | WDCS_DSC | WDCS_DRQ))
  3861. +             != (WDCS_DRDY | WDCS_DSC | WDCS_DRQ)) {
  3862. +             wderror(d_link, NULL, "wdcintr: read intr before drq");
  3863. +             wdcunwedge(wdc);
  3864. +             return 1;
  3865. +         }
  3866. +         /* Pull in data. */
  3867. +         if ((d_link->sc_flags & WDF_32BIT) == 0)
  3868. +             insw(wdc->sc_iobase+wd_data, xfer->databuf + xfer->c_skip, 
  3869. +                 xfer->c_nbytes >> 1);
  3870. +         else
  3871. +             insl(wdc->sc_iobase+wd_data, xfer->databuf + xfer->c_skip, 
  3872. +                 xfer->c_nbytes >> 2);
  3873. +     }
  3874. +     
  3875. +     /* If we encountered any abnormalities, flag it as a soft error. */
  3876. +     if (wdc->sc_errors > 0 ||
  3877. +         (wdc->sc_status & WDCS_CORR) != 0) {
  3878. +         wderror(d_link, xfer->c_bp, "soft error (corrected)");
  3879. +         wdc->sc_errors = 0;
  3880. +     }
  3881. +     
  3882. +     /* Adjust pointers for the next block, if any. */
  3883. +     xfer->c_blkno += xfer->c_nblks;
  3884. +     xfer->c_skip += xfer->c_nbytes;
  3885. +     xfer->c_bcount -= xfer->c_nbytes;
  3886. +     /* See if this transfer is complete. */
  3887. +     if (xfer->c_bcount > 0)
  3888. +         goto restart;
  3889. + done:
  3890. +     /* Done with this transfer, with or without error. */
  3891. +     wdc_ata_done(wdc, xfer);
  3892. +     return 0;
  3893. + restart:
  3894. +     /* Start the next operation */
  3895. + #ifdef WDDEBUG
  3896. +     printf("wdc_ata_start from wdcintr flags %d\n",wdc->sc_flags);
  3897. + #endif
  3898. +     wdc_ata_start(wdc, xfer);
  3899. +     return 1;
  3900. + }
  3901. + int
  3902. + wdcreset(wdc)
  3903. +     struct wdc_softc *wdc;
  3904. + {
  3905. +     int iobase = wdc->sc_iobase;
  3906. +     /* Reset the device. */
  3907. +     if (wdresethack) {
  3908. +         outb(iobase+wd_ctlr, WDCTL_RST | WDCTL_IDS);
  3909. +         delay(1000);
  3910. +         outb(iobase+wd_ctlr, WDCTL_IDS);
  3911. +         delay(1000);
  3912. +         (void) inb(iobase+wd_error);
  3913. +         outb(iobase+wd_ctlr, WDCTL_4BIT);
  3914. +     }
  3915. +     if (wait_for_unbusy(wdc) < 0) {
  3916. +         printf("%s: reset failed\n", wdc->sc_dev.dv_xname);
  3917. +         return 1;
  3918. +     }
  3919. +     return 0;
  3920. + }
  3921. + void
  3922. + wdcrestart(arg)
  3923. +     void *arg;
  3924. + {
  3925. +     struct wdc_softc *wdc = arg;
  3926. +     int s;
  3927. +     s = splbio();
  3928. +     wdcstart(wdc);
  3929. +     splx(s);
  3930. + }
  3931. + /*
  3932. +  * Unwedge the controller after an unexpected error.  We do this by resetting
  3933. +  * it, marking all drives for recalibration, and stalling the queue for a short
  3934. +  * period to give the reset time to finish.
  3935. +  * NOTE: We use a timeout here, so this routine must not be called during
  3936. +  * autoconfig or dump.
  3937. +  */
  3938. + void
  3939. + wdcunwedge(wdc)
  3940. +     struct wdc_softc *wdc;
  3941. + {
  3942. +     int unit;
  3943. + #ifdef ATAPI_DEBUG
  3944. +     printf("wdcunwedge\n");
  3945. + #endif
  3946. +     untimeout(wdctimeout, wdc);
  3947. +     wdc->sc_flags &= ~WDCF_IRQ_WAIT;
  3948. +     (void) wdcreset(wdc);
  3949. +     /* Schedule recalibrate for all drives on this controller. */
  3950. +     for (unit = 0; unit < 2; unit++) {
  3951. +         if (!wdc->d_link[unit]) continue;
  3952. +         if (wdc->d_link[unit]->sc_state > RECAL)
  3953. +             wdc->d_link[unit]->sc_state = RECAL;
  3954. +     }
  3955. +     wdc->sc_flags |= WDCF_ERROR;
  3956. +     ++wdc->sc_errors;
  3957. +     /* Wake up in a little bit and restart the operation. */
  3958. + #ifdef WDDEBUG
  3959. +     printf("wdcrestart from wdcunwedge\n");
  3960. + #endif
  3961. +     wdc->sc_flags &= ~WDCF_ACTIVE;
  3962. +     timeout(wdcrestart, wdc, RECOVERYTIME);
  3963. + }
  3964. + int
  3965. + wdcwait(wdc, mask)
  3966. +     struct wdc_softc *wdc;
  3967. +     int mask;
  3968. + {
  3969. +     int iobase = wdc->sc_iobase;
  3970. +     int timeout = 0;
  3971. +     u_char status;
  3972. + #ifdef WDCNDELAY_DEBUG
  3973. +     extern int cold;
  3974. + #endif
  3975. + #ifdef WDDEBUG
  3976. +     printf("wdcwait\n");
  3977. + #endif
  3978. +         
  3979. +     for (;;) {
  3980. +         wdc->sc_status = status = inb(iobase+wd_status);
  3981. +         /*
  3982. +          * XXX
  3983. +          * If a single slave ATAPI device is attached, it may
  3984. +          * have released the bus. Select it and try again.
  3985. +          */
  3986. +         if (status == 0xff && wdc->sc_flags & WDCF_ONESLAVE) {
  3987. +             outb(iobase+wd_sdh, WDSD_IBM | 0x10);
  3988. +             wdc->sc_status = status = inb(iobase+wd_status);
  3989. +         }
  3990. +         if ((status & WDCS_BSY) == 0 && (status & mask) == mask)
  3991. +             break;
  3992. +         if (++timeout > WDCNDELAY) {
  3993. + #ifdef ATAPI_DEBUG2
  3994. +             printf("wdcwait: timeout, status %x\n", status);
  3995. + #endif
  3996. +             return -1;
  3997. +         }
  3998. +         delay(WDCDELAY);
  3999. +     }
  4000. +     if (status & WDCS_ERR) {
  4001. +         wdc->sc_error = inb(iobase+wd_error);
  4002. +         return WDCS_ERR;
  4003. +     }
  4004. + #ifdef WDCNDELAY_DEBUG
  4005. +     /* After autoconfig, there should be no long delays. */
  4006. +     if (!cold && timeout > WDCNDELAY_DEBUG) {
  4007. +         struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first;
  4008. +         if (xfer == NULL)
  4009. +             printf("%s: warning: busy-wait took %dus\n",
  4010. +                 wdc->sc_dev.dv_xname, WDCDELAY * timeout);
  4011. +         else 
  4012. +             printf("%s(%s): warning: busy-wait took %dus\n",
  4013. +                 wdc->sc_dev.dv_xname,
  4014. +                 ((struct device*)xfer->d_link->wd_softc)->dv_xname,
  4015. +                 WDCDELAY * timeout);
  4016. +     }
  4017. + #endif
  4018. +     return 0;
  4019. + }
  4020. + void
  4021. + wdctimeout(arg)
  4022. +     void *arg;
  4023. + {
  4024. +     struct wdc_softc *wdc = (struct wdc_softc *)arg;
  4025. +     int s;
  4026. + #ifdef WDDEBUG
  4027. +     printf("wdctimeout\n");
  4028. + #endif
  4029. +     s = splbio();
  4030. +     if ((wdc->sc_flags & WDCF_IRQ_WAIT) != 0) {
  4031. +         wdc->sc_flags &= ~WDCF_IRQ_WAIT;
  4032. +         wdcerror(wdc, "lost interrupt");
  4033. +         wdcunwedge(wdc);
  4034. +     } else
  4035. +         wdcerror(wdc, "missing untimeout");
  4036. +     splx(s);
  4037. + }
  4038. + /*
  4039. +  * Wait for the drive to become ready and send a command.
  4040. +  * Return -1 if busy for too long or 0 otherwise.
  4041. +  * Assumes interrupts are blocked.
  4042. +  */
  4043. + int
  4044. + wdccommand(d_link, command, drive, cylin, head, sector, count)
  4045. +         struct wd_link *d_link;
  4046. +         int command;
  4047. +         int drive, cylin, head, sector, count;
  4048. + {
  4049. +         struct wdc_softc *wdc = (void*)d_link->wdc_softc;
  4050. +         int iobase = wdc->sc_iobase;
  4051. +         int stat;
  4052. + #ifdef WDDEBUG
  4053. +     printf("wdccommand drive %d\n",drive);
  4054. + #endif
  4055. + #if defined(DIAGNOSTIC) && defined(WDCDEBUG)
  4056. +     if ((wdc->sc_flags & WDCF_ACTIVE) == 0 )
  4057. +         printf("wdccommand: controler not active (drive %d)\n", drive);
  4058. + #endif
  4059. +         /* Select drive, head, and addressing mode. */
  4060. +         outb(iobase+wd_sdh, WDSD_IBM | (drive << 4) | head);
  4061. +         /* Wait for it to become ready to accept a command. */
  4062. +         if (command == WDCC_IDP || d_link->type == BUS)
  4063. +                 stat = wait_for_unbusy(wdc);
  4064. +         else
  4065. +                 stat = wdcwait(wdc, WDCS_DRDY);
  4066. +         if (stat < 0) {
  4067. + #ifdef ATAPI_DEBUG
  4068. +                 printf("wdcommand:xfer failed (wait_for_unbusy) status %d\n",stat);
  4069. + #endif
  4070. +                 return -1;
  4071. +          }
  4072. +         /* Load parameters. */
  4073. +         if (d_link->type == DRIVE && d_link->sc_lp->d_type == DTYPE_ST506)
  4074. +                 outb(iobase+wd_precomp, d_link->sc_lp->d_precompcyl / 4);
  4075. +         else
  4076. +                 outb(iobase+wd_features, 0);
  4077. +         outb(iobase+wd_cyl_lo, cylin);
  4078. +         outb(iobase+wd_cyl_hi, cylin >> 8);
  4079. +         outb(iobase+wd_sector, sector);
  4080. +         outb(iobase+wd_seccnt, count);
  4081. +         /* Send command. */
  4082. +         outb(iobase+wd_command, command);
  4083. +         return 0;
  4084. + }
  4085. + /*
  4086. +  * Simplified version of wdccommand().
  4087. +  */
  4088. + int
  4089. + wdccommandshort(wdc, drive, command)
  4090. +         struct wdc_softc *wdc;
  4091. +         int drive;
  4092. +         int command;
  4093. + {
  4094. +         int iobase = wdc->sc_iobase;
  4095. + #ifdef WDDEBUG
  4096. +     printf("wdccommandshort\n");
  4097. + #endif
  4098. + #if defined(DIAGNOSTIC) && defined(WDCDEBUG)
  4099. +     if ((wdc->sc_flags & WDCF_ACTIVE) == 0 )
  4100. +         printf("wdccommandshort: controler not active (drive %d)\n", drive);
  4101. + #endif
  4102. +         /* Select drive. */
  4103. +         outb(iobase+wd_sdh, WDSD_IBM | (drive << 4));
  4104. +         if (wdcwait(wdc, WDCS_DRDY) < 0)
  4105. +                 return -1;
  4106. +         outb(iobase+wd_command, command);
  4107. +         return 0;
  4108. + }
  4109. + #ifndef __BDEVSW_DUMP_OLD_TYPE
  4110. + /* #define WD_DUMP_NOT_TRUSTED*/ /* if you just want to watch */
  4111. + static int wddumprecalibrated;
  4112. + int
  4113. + wdcdump(d_link, blkno, nblks, va)
  4114. + struct wd_link *d_link;
  4115. + daddr_t blkno;
  4116. + int nblks;
  4117. + caddr_t va;
  4118. + {
  4119. +     struct wdc_softc *wdc = (void*)d_link->wdc_softc;
  4120. +     struct disklabel *lp = d_link->sc_lp;
  4121. +     /* Recalibrate, if first dump transfer. */
  4122. +     wdc->sc_flags  |= WDCF_ACTIVE;
  4123. +     if (wddumprecalibrated == 0) {
  4124. +         if (wdccommandshort(wdc, d_link->sc_drive, WDCC_RECAL) != 0 ||
  4125. +         wait_for_ready(wdc) != 0 ||
  4126. +         wdsetctlr(d_link) != 0 || wait_for_ready(wdc) != 0) {
  4127. +                 wdcerror(wdc, "wdcdump: recal failed");
  4128. +              return EIO;
  4129. +         }
  4130. +     }
  4131. +     while (nblks > 0) {
  4132. +         daddr_t xlt_blkno = blkno;
  4133. +         long cylin, head, sector;
  4134. +     
  4135. +         if ((lp->d_flags & D_BADSECT) != 0) {
  4136. +             long blkdiff;
  4137. +             int i;
  4138. +             for (i = 0; (blkdiff = d_link->sc_badsect[i]) != -1; i++) {
  4139. +                 blkdiff -= xlt_blkno;
  4140. +                 if (blkdiff < 0)
  4141. +                     continue;
  4142. +                 if (blkdiff == 0) {
  4143. +                     /* Replace current block of transfer. */
  4144. +                     xlt_blkno = lp->d_secperunit -
  4145. +                         lp->d_nsectors - i - 1;
  4146. +                 }
  4147. +                 break;
  4148. +             }
  4149. +             /* Tranfer is okay now. */
  4150. +         }
  4151. +      
  4152. +         if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0) {
  4153. +             sector = (xlt_blkno >> 0) & 0xff;
  4154. +             cylin = (xlt_blkno >> 8) & 0xffff;
  4155. +             head = (xlt_blkno >> 24) & 0xf;
  4156. +             head |= WDSD_LBA;
  4157. +         } else {
  4158. +             sector = xlt_blkno % lp->d_nsectors;
  4159. +             sector++;   /* Sectors begin with 1, not 0. */
  4160. +             xlt_blkno /= lp->d_nsectors;
  4161. +             head = xlt_blkno % lp->d_ntracks;
  4162. +             xlt_blkno /= lp->d_ntracks;
  4163. +             cylin = xlt_blkno;
  4164. +             head |= WDSD_CHS;
  4165. +         }
  4166. + #ifndef WD_DUMP_NOT_TRUSTED
  4167. +         if (wdccommand(d_link, WDCC_WRITE, d_link->sc_drive, cylin, head, sector, 1) != 0 ||
  4168. +             wait_for_drq(wdc) != 0) {
  4169. +             wdcerror(wdc, "wddump: write failed");
  4170. +             return EIO;
  4171. +         }
  4172. +    
  4173. +         outsw(wdc->sc_iobase+wd_data, va, lp->d_secsize >> 1);
  4174. +    
  4175. +         /* Check data request (should be done). */
  4176. +         if (wait_for_ready(wdc) != 0) {
  4177. +             wdcerror(wdc, "wddump: timeout waiting for ready");
  4178. +             return EIO;
  4179. +         }
  4180. + #else   /* WD_DUMP_NOT_TRUSTED */
  4181. +         /* Let's just talk about this first... */
  4182. +         printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
  4183. +             d_link->sc_drive, va, cylin, head, sector);
  4184. +         delay(500 * 1000);  /* half a second */
  4185. + #endif
  4186. +         /* update block count */
  4187. +         nblks -= 1;
  4188. +         blkno += 1;
  4189. +         va += lp->d_secsize;
  4190. +     }
  4191. +     wdc->sc_flags  &= ~WDCF_ACTIVE;
  4192. +     return 0;
  4193. + }
  4194. + #endif
  4195. + void wdc_ata_done(wdc, xfer)
  4196. + struct wdc_softc *wdc;
  4197. + struct wdc_xfer *xfer;
  4198. + {
  4199. +     int s;
  4200. +     struct buf *bp = xfer->c_bp;
  4201. +     struct wd_link *d_link = xfer->d_link;
  4202. + #ifdef WDDEBUG
  4203. +     printf("wdc_ata_done\n");
  4204. + #endif
  4205. +     /* remove this command from xfer queue */
  4206. +     s = splbio();
  4207. +     TAILQ_REMOVE(&wdc->sc_xfer, xfer, c_xferchain);
  4208. +     wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
  4209. +     wdc->sc_errors = 0;
  4210. +     if (bp) {
  4211. +         if (xfer->c_flags & C_ERROR) {
  4212. +             bp->b_flags |= B_ERROR;
  4213. +             bp->b_error = EIO;
  4214. +         }
  4215. +         bp->b_resid = xfer->c_bcount;
  4216. +         wddone(d_link, bp);
  4217. +         biodone(bp);
  4218. +     } else {
  4219. +         wakeup(xfer->databuf);
  4220. +     }
  4221. +     xfer->c_skip = 0;
  4222. +     wdc_free_xfer(xfer);
  4223. +     d_link->openings++;
  4224. +     wdstart((void*)d_link->wd_softc);
  4225. + #ifdef WDDEBUG
  4226. +     printf("wdcstart from wdc_ata_done, flags %d\n",wdc->sc_flags);
  4227. + #endif
  4228. +     wdcstart(wdc);
  4229. +     splx(s);
  4230. + }
  4231. + void wdc_exec_xfer(d_link, xfer)
  4232. + struct wd_link *d_link;
  4233. + struct wdc_xfer *xfer;
  4234. + {
  4235. +    struct wdc_softc *wdc=(struct wdc_softc *)d_link->wdc_softc;
  4236. +    int s;
  4237. +   
  4238. + #ifdef WDDEBUG
  4239. +     printf("wdc_exec_xfer\n");
  4240. + #endif
  4241. +     s = splbio();
  4242. +    /* insert at the end of command list */
  4243. +    TAILQ_INSERT_TAIL(&wdc->sc_xfer,xfer , c_xferchain)
  4244. + #ifdef WDDEBUG
  4245. +     printf("wdcstart from wdc_exec_xfer, flags %d\n",wdc->sc_flags);
  4246. + #endif
  4247. +     wdcstart(wdc);
  4248. +     splx(s);
  4249. + }   
  4250. + struct wdc_xfer *
  4251. + wdc_get_xfer(c_link,flags)
  4252. + struct wdc_link *c_link;
  4253. + int flags;
  4254. + {
  4255. +     struct wdc_xfer *xfer;
  4256. +     int s;
  4257. +     s = splbio();
  4258. +     if (xfer = xfer_free_list.lh_first) {
  4259. +         LIST_REMOVE(xfer, free_list);
  4260. +         splx(s);
  4261. + #ifdef DIAGNOSTIC
  4262. +         if ((xfer->c_flags & C_INUSE) != 0) panic("xfer already in use\n");
  4263. + #endif
  4264. +     } else {
  4265. +         splx(s);
  4266. + #ifdef ATAPI_DEBUG
  4267. +         printf("wdc:making xfer %d\n",wdc_nxfer);
  4268. + #endif
  4269. +         xfer = malloc(sizeof(*xfer), M_DEVBUF,
  4270. +         ((flags & IDE_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK));
  4271. +         if (!xfer) {
  4272. +             return 0;
  4273. +         }
  4274. + #ifdef DIAGNOSTIC
  4275. +         xfer->c_flags &= ~C_INUSE;
  4276. + #endif
  4277. + #ifdef ATAPI_DEBUG
  4278. +         wdc_nxfer++;
  4279. + #endif
  4280. +     }
  4281. + #ifdef DIAGNOSTIC
  4282. +     if ((xfer->c_flags & C_INUSE) != 0) panic("xfer already in use\n");
  4283. + #endif
  4284. +     bzero(xfer,sizeof(struct wdc_xfer));
  4285. +     xfer->c_flags = C_INUSE;
  4286. +     xfer->c_link = c_link;
  4287. +     return xfer;
  4288. + }
  4289. + void
  4290. + wdc_free_xfer(xfer)
  4291. +     struct wdc_xfer *xfer;
  4292. + {
  4293. +     int s;
  4294. +     s = splbio();
  4295. +     xfer->c_flags &= ~C_INUSE;
  4296. +     LIST_INSERT_HEAD(&xfer_free_list, xfer, free_list);
  4297. +     splx(s);
  4298. + }
  4299. + /*
  4300. +  * Implement operations needed before read/write.
  4301. +  * Returns 0 if operation still in progress, 1 if completed.
  4302. +  */
  4303. + int
  4304. + wdccontrol(d_link)
  4305. +     struct wd_link *d_link;
  4306. + {
  4307. +     struct wdc_softc *wdc = (void *)d_link->wdc_softc;
  4308. + #ifdef WDDEBUG
  4309. +     printf("wdccontrol\n");
  4310. + #endif
  4311. +     switch (d_link->sc_state) {
  4312. +     case RECAL:         /* Set SDH, step rate, do recal. */
  4313. +         if (wdccommandshort(wdc, d_link->sc_drive, WDCC_RECAL) != 0) {
  4314. +             wderror(d_link, NULL, "wdccontrol: recal failed (1)");
  4315. +             goto bad;
  4316. +         }
  4317. +         d_link->sc_state = RECAL_WAIT;
  4318. +         break;
  4319. +     case RECAL_WAIT:
  4320. +         if (wdc->sc_status & WDCS_ERR) {
  4321. +             wderror(d_link, NULL, "wdccontrol: recal failed (2)");
  4322. +             goto bad;
  4323. +         }
  4324. +         /* fall through */
  4325. +     case GEOMETRY:
  4326. +         if ((d_link->sc_params.wdp_capabilities & WD_CAP_LBA) != 0)
  4327. +             goto multimode;
  4328. +         if (wdsetctlr(d_link) != 0) {
  4329. +             /* Already printed a message. */
  4330. +             goto bad;
  4331. +         }
  4332. +         d_link->sc_state = GEOMETRY_WAIT;
  4333. +         break;
  4334. +     case GEOMETRY_WAIT:
  4335. +         if (wdc->sc_status & WDCS_ERR) {
  4336. +             wderror(d_link, NULL, "wdccontrol: geometry failed");
  4337. +             goto bad;
  4338. +         }
  4339. +         /* fall through */
  4340. +     case MULTIMODE:
  4341. +     multimode:
  4342. +         if (d_link->sc_mode != WDM_PIOMULTI)
  4343. +             goto open;
  4344. +         outb(wdc->sc_iobase+wd_seccnt, d_link->sc_multiple);
  4345. +         if (wdccommandshort(wdc, d_link->sc_drive, WDCC_SETMULTI) != 0) {
  4346. +             wderror(d_link, NULL, "wdccontrol: setmulti failed (1)");
  4347. +             goto bad;
  4348. +         }
  4349. +         d_link->sc_state = MULTIMODE_WAIT;
  4350. +         break;
  4351. +     case MULTIMODE_WAIT:
  4352. +         if (wdc->sc_status & WDCS_ERR) {
  4353. +             wderror(d_link, NULL, "wdccontrol: setmulti failed (2)");
  4354. +             goto bad;
  4355. +         }
  4356. +         /* fall through */
  4357. +     case OPEN:
  4358. +     open:
  4359. +         wdc->sc_errors = 0;
  4360. +         d_link->sc_state = OPEN;
  4361. +         /*
  4362. +          * The rest of the initialization can be done by normal means.
  4363. +          */
  4364. +         return 1;
  4365. +     bad:
  4366. +         wdcunwedge(wdc);
  4367. +         return 0;
  4368. +     }
  4369. +     wdc->sc_flags |= WDCF_IRQ_WAIT;
  4370. +     timeout(wdctimeout, wdc, WAITTIME);
  4371. +     return 0;
  4372. + }
  4373. + /*
  4374. +  * Get the drive parameters, if ESDI or ATA, or create fake ones for ST506.
  4375. +  */
  4376. + int
  4377. + wdc_get_parms(d_link)
  4378. +     struct wd_link *d_link;
  4379. + {
  4380. +     struct wdc_softc *wdc = (struct wdc_softc *)d_link->wdc_softc;
  4381. +     int i;
  4382. +     char tb[DEV_BSIZE];
  4383. +     int s, error;
  4384. +     /*
  4385. +      * XXX
  4386. +      * The locking done here, and the length of time this may keep the rest
  4387. +      * of the system suspended, is a kluge.  This should be rewritten to
  4388. +      * set up a transfer and queue it through wdstart(), but it's called
  4389. +      * infrequently enough that this isn't a pressing matter.
  4390. +      */
  4391. +     s = splbio();
  4392. +     while ((wdc->sc_flags & WDCF_ACTIVE) != 0) {
  4393. +         wdc->sc_flags |= WDCF_WANTED;
  4394. +         if ((error = tsleep(wdc, PRIBIO | PCATCH, "wdprm", 0)) != 0) {
  4395. +             splx(s);
  4396. +             return error;
  4397. +         }
  4398. +     }
  4399. +     wdc->sc_flags |= WDCF_ACTIVE;
  4400. +     if (wdccommandshort(wdc, d_link->sc_drive, WDCC_IDENTIFY) != 0 ||
  4401. +         wait_for_drq(wdc) != 0) {
  4402. +         /*
  4403. +          * We `know' there's a drive here; just assume it's old.
  4404. +          * This geometry is only used to read the MBR and print a
  4405. +          * (false) attach message.
  4406. +          */
  4407. +         strncpy(d_link->sc_lp->d_typename, "ST506",
  4408. +             sizeof d_link->sc_lp->d_typename);
  4409. +         d_link->sc_lp->d_type = DTYPE_ST506;
  4410. +         strncpy(d_link->sc_params.wdp_model, "unknown",
  4411. +             sizeof d_link->sc_params.wdp_model);
  4412. +         d_link->sc_params.wdp_config = WD_CFG_FIXED;
  4413. +         d_link->sc_params.wdp_cylinders = 1024;
  4414. +         d_link->sc_params.wdp_heads = 8;
  4415. +         d_link->sc_params.wdp_sectors = 17;
  4416. +         d_link->sc_params.wdp_maxmulti = 0;
  4417. +         d_link->sc_params.wdp_usedmovsd = 0;
  4418. +         d_link->sc_params.wdp_capabilities = 0;
  4419. +     } else {
  4420. +         strncpy(d_link->sc_lp->d_typename, "ESDI/IDE",
  4421. +             sizeof d_link->sc_lp->d_typename);
  4422. +         d_link->sc_lp->d_type = DTYPE_ESDI;
  4423. +         /* Read in parameter block. */
  4424. +         insw(wdc->sc_iobase+wd_data, tb, sizeof(tb) / sizeof(short));
  4425. +         bcopy(tb, &d_link->sc_params, sizeof(struct wdparams));
  4426. +         /* Shuffle string byte order. */
  4427. +         for (i = 0; i < sizeof(d_link->sc_params.wdp_model); i += 2) {
  4428. +             u_short *p;
  4429. +             p = (u_short *)(d_link->sc_params.wdp_model + i);
  4430. +             *p = ntohs(*p);
  4431. +         }
  4432. +     }
  4433. +     /* Clear any leftover interrupt. */
  4434. +     (void) inb(wdc->sc_iobase+wd_status);
  4435. +     /* Restart the queue. */
  4436. + #ifdef WDDEBUG
  4437. +     printf("wdcstart from wdc_get_parms flags %d\n",wdc->sc_flags);
  4438. + #endif
  4439. +     wdc->sc_flags &= ~WDCF_ACTIVE;
  4440. +     wdcstart(wdc);
  4441. +     splx(s);
  4442. +     return 0;
  4443. + }
  4444. + void
  4445. + wdcerror(wdc, msg) 
  4446. +     struct wdc_softc *wdc;
  4447. +     char *msg;
  4448. + {
  4449. +     struct wdc_xfer *xfer = wdc->sc_xfer.tqh_first;
  4450. +     if (xfer == NULL)
  4451. +         printf("%s: %s\n", wdc->sc_dev.dv_xname, msg);
  4452. +     else
  4453. +         printf("%s(%s): %s\n", wdc->sc_dev.dv_xname, 
  4454. +             ((struct device*)xfer->d_link->wd_softc)->dv_xname, msg);
  4455. +  }
  4456. + int wdc_atapi_get_params(ab_link, drive, id)
  4457. + struct bus_link *ab_link;
  4458. + u_int8_t drive;
  4459. + struct atapi_identify *id;
  4460. + {
  4461. +     struct wdc_softc *wdc = (void*)ab_link->wdc_softc;
  4462. +     int status, len, excess = 0;
  4463. +     int s, error;
  4464. +     if (wdc->d_link[drive] != 0) {
  4465. + #ifdef ATAPI_DEBUG_PROBE
  4466. +         printf("wdc_atapi_get_params: WD drive %d\n", drive);
  4467. + #endif
  4468. +         return 0;
  4469. +     }
  4470. +     /* If there is only one ATAPI slave ion the bus,don't probe
  4471. +        drive 0 (master) */
  4472. +     if (wdc->sc_flags & WDCF_ONESLAVE && drive != 1)
  4473. +         return 0;
  4474. + #ifdef ATAPI_DEBUG_PROBE
  4475. +     printf("wdc_atapi_get_params: probing drive %d\n", drive);
  4476. + #endif
  4477. +     /*
  4478. +      * XXX
  4479. +      * The locking done here, and the length of time this may keep the rest
  4480. +      * of the system suspended, is a kluge.  This should be rewritten to
  4481. +      * set up a transfer and queue it through wdstart(), but it's called
  4482. +      * infrequently enough that this isn't a pressing matter.
  4483. +      */
  4484. +     s = splbio();
  4485. +     while ((wdc->sc_flags & WDCF_ACTIVE) != 0) {
  4486. +         wdc->sc_flags |= WDCF_WANTED;
  4487. +         if ((error = tsleep(wdc, PRIBIO | PCATCH, "atprm", 0)) != 0) {
  4488. +             splx(s);
  4489. +             return error;
  4490. +         }
  4491. +     }
  4492. +     wdc->sc_flags |= WDCF_ACTIVE;
  4493. +     error = 1;
  4494. +     (void)wdcreset(wdc);
  4495. +     if ((status = wdccommand((struct wd_link*)ab_link, ATAPI_SOFT_RESET, drive,
  4496. +         0, 0, 0, 0)) != 0) {
  4497. + #ifdef ATAPI_DEBUG
  4498. +         printf("wdc_atapi_get_params: ATAPI_SOFT_RESET failed for drive %d: status %d error %d\n", drive, status, wdc->sc_error);
  4499. + #endif
  4500. +         error = 0;
  4501. +         goto end;
  4502. +     } 
  4503. +     if ((status = wait_for_unbusy(wdc)) != 0 ) {
  4504. + #ifdef ATAPI_DEBUG
  4505. +         printf("wdc_atapi_get_params: wait_for_unbusy failed for drive %d: status %d error %d\n", drive, status, wdc->sc_error);
  4506. + #endif
  4507. +         error = 0;
  4508. +         goto end;
  4509. +     }
  4510. +     if (wdccommand((struct wd_link*)ab_link, ATAPI_IDENTIFY_DEVICE, drive, sizeof(struct atapi_identify), 0,
  4511. +     0, 0) != 0 || atapi_ready(wdc) != 0) {
  4512. + #ifdef ATAPI_DEBUG_PROBE
  4513. +         printf("ATAPI_IDENTIFY_DEVICE failed for drive %d\n",drive);
  4514. + #endif
  4515. +         error = 0;
  4516. +         goto end;
  4517. +     }
  4518. +     len = inb(wdc->sc_iobase + wd_cyl_lo) +
  4519. +         256 * inb(wdc->sc_iobase + wd_cyl_hi);
  4520. +     if (len != sizeof(struct atapi_identify)) {
  4521. +         printf("Warning drive %d returned %d/%d of indentify device data\n",
  4522. +             drive, len, sizeof(struct atapi_identify));
  4523. +         excess = len - sizeof(struct atapi_identify);
  4524. +         if (excess < 0) excess = 0;
  4525. +     }
  4526. +     insw(wdc->sc_iobase + wd_data, id,
  4527. +         sizeof(struct atapi_identify)/sizeof(short));
  4528. +     wdcbit_bucket(wdc, excess);
  4529. + end: /* Restart the queue. */
  4530. + #ifdef WDDEBUG
  4531. +     printf("wdcstart from wdc_atapi_get_parms flags %d\n",wdc->sc_flags);
  4532. + #endif
  4533. +     wdc->sc_flags &= ~WDCF_ACTIVE;
  4534. +     wdcstart(wdc);
  4535. +     splx(s);
  4536. +     return error;
  4537. + }
  4538. +     
  4539. + void wdc_atapi_send_command_packet(ab_link, acp)
  4540. + struct bus_link *ab_link;
  4541. + struct atapi_command_packet *acp;
  4542. + {
  4543. +     struct wdc_softc *wdc = (void*)ab_link->wdc_softc;
  4544. +     struct wdc_xfer *xfer;
  4545. +     int s;
  4546. +     u_int8_t flags = acp->flags & 0xff;
  4547. +     
  4548. +     if (flags & A_POLLED) {   /* Must use the queue and wdc_atapi_start */
  4549. +         struct wdc_xfer xfer_s;
  4550. +         int i;
  4551. + #ifdef ATAPI_DEBUG_WDC
  4552. +         printf("wdc_atapi_send_cmd: flags %ld drive %d cmdlen %d datalen %d",
  4553. +         acp->flags, acp->drive, acp->command_size, acp->data_size);
  4554. + #endif
  4555. +         xfer = &xfer_s;
  4556. +         bzero(xfer, sizeof(xfer_s));
  4557. +         xfer->c_flags = C_INUSE|C_ATAPI|acp->flags;
  4558. +         xfer->d_link = (struct wd_link*) ab_link;
  4559. +         xfer->c_link = ab_link->ctlr_link;
  4560. +         xfer->c_bp = acp->bp;
  4561. +         xfer->atapi_cmd = acp;
  4562. +         xfer->c_blkno = 0;
  4563. +         xfer->databuf = acp->databuf;
  4564. +         xfer->c_bcount = acp->data_size;
  4565. +         if (wait_for_unbusy (wdc) != 0) 
  4566. +             if (!(wdc->sc_status & WDCS_ERR)) {
  4567. +                 printf ("wdc_atapi_send_command: not ready, st = %02x\n",wdc->sc_status);
  4568. +                 acp->status = ERROR;
  4569. +                 return;
  4570. +             }
  4571. +         if (wdccommand ((struct wd_link*)ab_link, ATAPI_PACKET_COMMAND,
  4572. +     acp->drive, acp->data_size, 0, 0, 0) != 0) {
  4573. +             printf("can't send atapi paket command\n");
  4574. +             acp->status = ERROR;
  4575. +             return;
  4576. +         }
  4577. +         /* Wait for cmd i/o phase. */
  4578. +         for (i=20000; i>0; --i) {
  4579. +             int phase;
  4580. +             phase = (inb(wdc->sc_iobase + wd_ireason) & (WDCI_CMD | WDCI_IN)) |
  4581. +                 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
  4582. +             if (phase == PHASE_CMDOUT)
  4583. +                 break;
  4584. +             delay(10);
  4585. +         }
  4586. + #ifdef ATAPI_DEBUG_WDC
  4587. +         printf("Wait for cmd i/o phase: i= %d\n", i);
  4588. + #endif
  4589. +         outsw (wdc->sc_iobase + wd_data, acp->command,
  4590. +             acp->command_size/ sizeof (short));
  4591. +         /* Wait for data i/o phase. */
  4592. +         for (i=20000; i>0; --i) {
  4593. +             int phase;
  4594. +             phase = (inb(wdc->sc_iobase + wd_ireason) & (WDCI_CMD | WDCI_IN)) |
  4595. +                 (inb(wdc->sc_iobase + wd_status) & WDCS_DRQ);
  4596. +             if (phase != PHASE_CMDOUT) {
  4597. +                 break;
  4598. +             }
  4599. +             delay(10);
  4600. +         }
  4601. + #ifdef ATAPI_DEBUG_WDC
  4602. +         printf("Wait for data i/o phase: i= %d\n", i);
  4603. + #endif
  4604. +         while (wdc_atapi_intr(wdc, xfer)) {
  4605. +             for (i=2000; i>0; --i)
  4606. +                 if (! (inb (wdc->sc_iobase + wd_status) & WDCS_DRQ))
  4607. +                     break;
  4608. + #ifdef ATAPI_DEBUG_WDC
  4609. +             printf("wdc_atapi_intr: i=%d\n", i);
  4610. + #endif
  4611. +         }
  4612. +         wdc->sc_flags &= ~(WDCF_IRQ_WAIT | WDCF_SINGLE | WDCF_ERROR);
  4613. +         wdc->sc_errors = 0;
  4614. +         xfer->c_skip = 0;
  4615. +         return;
  4616. +     } else {   /* POLLED */
  4617. +         xfer = wdc_get_xfer(ab_link->ctlr_link, flags&A_NOSLEEP?IDE_NOSLEEP:0);
  4618. +         if (xfer == NULL) {
  4619. +             acp->status = ERROR;
  4620. +             return;
  4621. +         }
  4622. +         xfer->c_flags |= C_ATAPI|acp->flags;
  4623. +         xfer->d_link = (struct wd_link*) ab_link;
  4624. +         xfer->c_link = ab_link->ctlr_link;
  4625. +         xfer->c_bp = acp->bp;
  4626. +         xfer->atapi_cmd = acp;
  4627. +         xfer->c_blkno = 0;
  4628. +         xfer->databuf = acp->databuf;
  4629. +         xfer->c_bcount = acp->data_size;
  4630. +         wdc_exec_xfer((struct wd_link*)ab_link,xfer);
  4631. +         return;
  4632. +     }
  4633. + }
  4634. +         
  4635. + /* 
  4636. +    the bit bucket
  4637. +    */
  4638. + void wdcbit_bucket (wdc, size)
  4639. +     struct wdc_softc *wdc; 
  4640. +     int size;
  4641. + {
  4642. +     int iobase = wdc->sc_iobase; 
  4643. +     int i;
  4644. +  
  4645. +     for (i = 0 ; i < size / 2 ; i++) {
  4646. +     short null; 
  4647. +     (void) insw (iobase + wd_data, &null, 1);
  4648. +     } 
  4649. +  
  4650. +     if (size % 2)
  4651. +     (void) inb (iobase + wd_data);
  4652. + }
  4653. + int wdc_atapi_intr(wdc, xfer)
  4654. + struct wdc_softc *wdc;
  4655. + struct wdc_xfer *xfer;
  4656. + {
  4657. +     int len, phase, i;
  4658. +     int err, st, ire;
  4659. +     struct atapi_command_packet *acp = xfer->atapi_cmd;
  4660. +     if (wait_for_unbusy(wdc)<0) {
  4661. +         printf("wdc_atapi_intr: controller busy\n");
  4662. +         acp->status = ERROR;
  4663. +         acp->error = inb (wdc->sc_iobase + wd_error);
  4664. +         return 0;
  4665. +     }
  4666. + #ifdef ATAPI_DEBUG2
  4667. +      printf("wdc_atapi_intr: %s\n", wdc->sc_dev.dv_xname);
  4668. + #endif
  4669. +     len = inb (wdc->sc_iobase + wd_cyl_lo) +
  4670. +     256 * inb (wdc->sc_iobase + wd_cyl_hi);
  4671. +     st = inb(wdc->sc_iobase + wd_status);
  4672. +     err = inb(wdc->sc_iobase + wd_error);
  4673. +     ire = inb(wdc->sc_iobase + wd_ireason);
  4674. +     
  4675. +     phase = (ire & (WDCI_CMD | WDCI_IN)) | (st & WDCS_DRQ);
  4676. + #ifdef ATAPI_DEBUG_WDC
  4677. +     printf("wdc_atapi_intr: len %d st %d err %d ire %d :", len, st, err, ire);
  4678. + #endif
  4679. +     switch (phase) {
  4680. +     case PHASE_CMDOUT:
  4681. +         /* send packet command */
  4682. + #ifdef ATAPI_DEBUG_WDC
  4683. +         printf("PHASE_CMDOUT\n");
  4684. + #endif
  4685. + #ifdef ATAPI_DEBUG_WDC
  4686. +         {
  4687. +         int i;
  4688. +         char *c = (char*)acp->command;   
  4689. +         printf("wdc_atapi_intr: cmd ");
  4690. +         for(i=0;i<acp->command_size;i++) printf("%x ",c[i]);
  4691. +         printf("\n");
  4692. +         }
  4693. + #endif
  4694. +         wdc->sc_flags |= WDCF_IRQ_WAIT;
  4695. +         outsw (wdc->sc_iobase + wd_data, acp->command,
  4696. +             acp->command_size/ sizeof (short));
  4697. +         return 1;
  4698. +     case PHASE_DATAOUT:
  4699. +         /* write data */
  4700. + #ifdef ATAPI_DEBUG_WDC
  4701. +         printf("PHASE_DATAOUT\n");
  4702. + #endif
  4703. +         if ((acp->flags & (B_READ|B_WRITE)) != B_WRITE) {
  4704. +             printf("wdc_atapi_intr: bad data phase\n");
  4705. +             acp->status = ERROR;
  4706. +             return 1;
  4707. +         }
  4708. +         wdc->sc_flags |= WDCF_IRQ_WAIT;
  4709. +         if (xfer->c_bcount < len) {
  4710. +             printf("wdc_atapi_intr: warning: write only %d of %d requested bytes\n",
  4711. +             xfer->c_bcount, len);
  4712. +             outsw (wdc->sc_iobase + wd_data, xfer->databuf+xfer->c_skip,
  4713. +                         xfer->c_bcount/sizeof (short));
  4714. +             for(i = xfer->c_bcount; i<len; i+=sizeof(short))
  4715. +                 outw(wdc->sc_iobase + wd_data, 0);
  4716. +             xfer->c_bcount = 0;
  4717. +             return 1;
  4718. +         } else {
  4719. +             outsw (wdc->sc_iobase + wd_data, xfer->databuf+xfer->c_skip,
  4720. +                     len/sizeof (short));
  4721. +             xfer->c_skip += len;
  4722. +             xfer->c_bcount -= len;
  4723. +             return 1;
  4724. +         }
  4725. +     
  4726. +         case PHASE_DATAIN:
  4727. +             /* Read data */
  4728. + #ifdef ATAPI_DEBUG_WDC
  4729. +         printf("PHASE_DATAIN\n");
  4730. + #endif
  4731. +         if ((acp->flags & (B_READ|B_WRITE)) != B_READ) {
  4732. +             printf("wdc_atapi_intr: bad data phase\n");
  4733. +             acp->status = ERROR;
  4734. +             return 1;
  4735. +         }
  4736. +         wdc->sc_flags |= WDCF_IRQ_WAIT;
  4737. +         if (xfer->c_bcount < len) {
  4738. +             printf("wdc_atapi_intr: warning: reading only %d of %d bytes\n",
  4739. +                 xfer->c_bcount, len);
  4740. +             insw(wdc->sc_iobase + wd_data, xfer->databuf+xfer->c_skip,
  4741. +                 xfer->c_bcount/sizeof(short));
  4742. +             wdcbit_bucket(wdc, len - xfer->c_bcount);
  4743. +             xfer->c_bcount = 0;
  4744. +             return 1;
  4745. +         } else {
  4746. +             insw(wdc->sc_iobase + wd_data, xfer->databuf+xfer->c_skip,
  4747. +                 len/sizeof(short));
  4748. +             xfer->c_skip += len;
  4749. +             xfer->c_bcount -=len;
  4750. +             return 1;
  4751. +         }
  4752. +         case PHASE_ABORTED:
  4753. +         case PHASE_COMPLETED:
  4754. + #ifdef ATAPI_DEBUG_WDC
  4755. +         printf("PHASE_COMPLETED\n");
  4756. + #endif
  4757. +         if (st & WDCS_ERR)  {
  4758. +             acp->error = inb (wdc->sc_iobase + wd_error);
  4759. +             acp->status = ERROR;
  4760. +         }
  4761. + #ifdef ATAPI_DEBUG_WDC
  4762. +         if (xfer->c_bcount != 0) {
  4763. +             printf("wdc_atapi_intr warning: bcount value is %d after io\n",
  4764. +                 xfer->c_bcount );
  4765. +         }
  4766. + #endif
  4767. +         break;
  4768. +         default: 
  4769. +             printf("wdc_atapi_intr: unknown phase %d\n", phase);
  4770. +             acp->status = ERROR;
  4771. +     }
  4772. +     wdc_atapi_done(wdc, xfer);
  4773. +     return(0);
  4774. + }
  4775. + void
  4776. + wdc_atapi_done(wdc, xfer)
  4777. + struct wdc_softc *wdc;
  4778. + struct wdc_xfer *xfer;
  4779. + {
  4780. +     struct atapi_command_packet *acp = xfer->atapi_cmd;
  4781. +     int s;
  4782. +     acp->data_size = xfer->c_bcount;
  4783. +     s = splbio();
  4784. +     /* remove this command from xfer queue */
  4785. +     wdc->sc_errors = 0;
  4786. +     xfer->c_skip = 0;
  4787. +     if ((xfer->c_flags & A_POLLED) == 0) {
  4788. +         untimeout(wdctimeout, wdc);
  4789. +         TAILQ_REMOVE(&wdc->sc_xfer, xfer, c_xferchain);
  4790. +         wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
  4791. +         wdc_free_xfer(xfer);
  4792. + #ifdef ATAPI_DEBU
  4793. +         printf("wdc_atapi_done: atapi_done\n");
  4794. + #endif
  4795. +         atapi_done(acp);
  4796. + #ifdef WDDEBUG
  4797. +            printf("wdcstart from wdc_atapi_intr, flags %d\n",wdc->sc_flags);
  4798. + #endif
  4799. +         wdcstart(wdc);
  4800. +     } else {
  4801. +         wdc->sc_flags &= ~(WDCF_SINGLE | WDCF_ERROR | WDCF_ACTIVE);
  4802. +     }
  4803. +     splx(s);
  4804. + }
  4805. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/mainbus/wdlink.h sys/arch/arm32/mainbus/wdlink.h
  4806. *** sys/arch/arm32.orig/mainbus/wdlink.h    Thu Jan  1 01:00:00 1970
  4807. --- sys/arch/arm32/mainbus/wdlink.h    Thu Jun 13 02:57:04 1996
  4808. ***************
  4809. *** 0 ****
  4810. --- 1,112 ----
  4811. + /*
  4812. +  * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
  4813. +  *
  4814. +  * DMA and multi-sector PIO handling are derived from code contributed by
  4815. +  * Onno van der Linden.
  4816. +  *
  4817. +  * Atapi support added by Manuel Bouyer.
  4818. +  *
  4819. +  * Redistribution and use in source and binary forms, with or without
  4820. +  * modification, are permitted provided that the following conditions
  4821. +  * are met:
  4822. +  * 1. Redistributions of source code must retain the above copyright
  4823. +  *    notice, this list of conditions and the following disclaimer.
  4824. +  * 2. Redistributions in binary form must reproduce the above copyright
  4825. +  *    notice, this list of conditions and the following disclaimer in the
  4826. +  *    documentation and/or other materials provided with the distribution.
  4827. +  * 3. All advertising materials mentioning features or use of this software
  4828. +  *    must display the following acknowledgement:
  4829. +  *  This product includes software developed by Charles M. Hannum.
  4830. +  * 4. The name of the author may not be used to endorse or promote products
  4831. +  *    derived from this software without specific prior written permission.
  4832. +  *
  4833. +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  4834. +  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  4835. +  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  4836. +  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  4837. +  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  4838. +  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  4839. +  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  4840. +  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4841. +  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  4842. +  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4843. +  */
  4844. + #undef WDDEBUG
  4845. + /* #undef DIAGNOSTIC */
  4846. + struct wdc_link {
  4847. +     int flags;
  4848. +     int openings;
  4849. + };
  4850. + struct wd_link {
  4851. +     u_char type;  
  4852. + #define DRIVE 0
  4853. + #define BUS 1
  4854. +     caddr_t wdc_softc;
  4855. +     caddr_t wd_softc;
  4856. +     struct wdc_link *ctlr_link;
  4857. +     struct wdparams sc_params;
  4858. +     /* Long-term state: */
  4859. +     u_int8_t openings;
  4860. +     int sc_drive;                   /* physical unit number */
  4861. +     int sc_state;                   /* control state */
  4862. + #define RECAL           0               /* recalibrate */
  4863. + #define RECAL_WAIT      1               /* done recalibrating */
  4864. + #define GEOMETRY        2               /* upload geometry */
  4865. + #define GEOMETRY_WAIT   3               /* done uploading geometry */
  4866. + #define MULTIMODE       4               /* set multiple mode */
  4867. + #define MULTIMODE_WAIT  5               /* done setting multiple mode */
  4868. + #define OPEN            6               /* done with open */
  4869. +     int sc_mode;                    /* transfer mode */
  4870. + #define WDM_PIOSINGLE   0               /* single-sector PIO */
  4871. + #define WDM_PIOMULTI    1               /* multi-sector PIO */
  4872. + #define WDM_DMA         2               /* DMA */
  4873. +     int sc_multiple;                /* multiple for WDM_PIOMULTI */
  4874. +     int sc_flags;                   /* drive characteistics found */
  4875. + #define WDF_LOCKED      0x01
  4876. + #define WDF_WANTED      0x02
  4877. + #define WDF_WLABEL      0x04            /* label is writable */
  4878. + #define WDF_LABELLING   0x08            /* writing label */
  4879. + /* XXX Nothing resets this yet, but disk change sensing will when ATAPI is
  4880. +    implemented. */
  4881. + #define WDF_LOADED      0x10            /* parameters loaded */
  4882. + #define WDF_32BIT       0x20            /* can do 32-bit transfer */
  4883. + #define WDF_WAIT         0x40            /* waiting for resourses */
  4884. +     daddr_t sc_badsect[127];        /* 126 plus trailing -1 marker */
  4885. +     struct disklabel * sc_lp;    /* label info for this disk */
  4886. + };
  4887. + struct wdc_xfer {
  4888. +     struct wdc_link *c_link;   /* controller structure info */
  4889. +     struct wd_link *d_link;   /* drive/bus structure info */
  4890. +     volatile long c_flags; /* handle also B_READ and B_WRITE */
  4891. + #define C_INUSE 0x01
  4892. + #define C_ATAPI 0x02
  4893. + #define C_ERROR 0x04
  4894. +     /* Information about the current transfer  */
  4895. +     struct buf *c_bp;
  4896. +     void *atapi_cmd;
  4897. +     void* databuf;
  4898. +     daddr_t c_blkno;       /* starting block number */
  4899. +     int c_bcount;          /* byte count left */
  4900. +     int c_skip;            /* bytes already transferred */
  4901. +     int c_nblks;           /* number of blocks currently transferring */
  4902. +     int c_nbytes;          /* number of bytes currently transferring */
  4903. +     u_long c_p_offset;  /* offset of the partition */
  4904. +     TAILQ_ENTRY(wdc_xfer) c_xferchain;
  4905. +     LIST_ENTRY(wdc_xfer) free_list;
  4906. + };
  4907. + void wdc_exec_xfer __P((struct wd_link *, struct wdc_xfer *));
  4908. + struct wdc_xfer * wdc_get_xfer __P((struct wdc_link *, int));
  4909. + int wdc_get_parms __P((struct wd_link *));
  4910. + void wderror __P((struct wd_link* , struct buf *, char *));
  4911. + void wddone __P((struct wd_link*, struct buf*));
  4912. + int wdccommand __P((struct wd_link *, int, int, int, int, int, int));
  4913. + int wdcdumpprecalibrated __P((struct wd_link *));
  4914. + #define IDE_NOSLEEP 0x01
  4915. diff -c -r -N --exclude exp --exclude compile sys/arch/arm32.orig/mainbus/wdreg.h sys/arch/arm32/mainbus/wdreg.h
  4916. *** sys/arch/arm32.orig/mainbus/wdreg.h    Sun May 12 22:34:06 1996
  4917. --- sys/arch/arm32/mainbus/wdreg.h    Thu Jun 13 02:57:04 1996
  4918. ***************
  4919. *** 47,52 ****
  4920. --- 47,53 ----
  4921.   #define    wd_precomp    0x004    /* write precompensation (W) */
  4922.   #define    wd_features    0x004    /* features (W) */
  4923.   #define    wd_seccnt    0x008    /* sector count (R/W) */
  4924. + #define wd_ireason    0x008   /* interrupt reason (R/W) (for atapi) */
  4925.   #define    wd_sector    0x00c    /* first sector number (R/W) */
  4926.   #define    wd_cyl_lo    0x010    /* cylinder address, low byte (R/W) */
  4927.   #define    wd_cyl_hi    0x014    /* cylinder address, high byte (R/W) */
  4928. ***************
  4929. *** 119,124 ****
  4930. --- 120,147 ----
  4931.   #define    WDSD_CHS    0x00    /* cylinder/head/sector addressing */
  4932.   #define    WDSD_LBA    0x40    /* logical block addressing */
  4933.   
  4934. + /* Commands for ATAPI devices */
  4935. + #define ATAPI_CHECK_POWER_MODE      0xe5
  4936. + #define ATAPI_EXEC_DRIVE_DIAGS      0x90
  4937. + #define ATAPI_IDLE_IMMEDIATE        0xe1
  4938. + #define ATAPI_NOP           0x00
  4939. + #define ATAPI_PACKET_COMMAND        0xa0
  4940. + #define ATAPI_IDENTIFY_DEVICE       0xa1
  4941. + #define ATAPI_SOFT_RESET        0x08
  4942. + #define ATAPI_SET_FEATURES      0xef
  4943. + #define ATAPI_SLEEP         0xe6
  4944. + #define ATAPI_STANDBY_IMMEDIATE     0xe0
  4945. + /* ireason */
  4946. + #define WDCI_CMD         0x01    /* command(1) or data(0) */
  4947. + #define WDCI_IN          0x02    /* transfer to(1) or from(0) the host */
  4948. + #define WDCI_RELEASE     0x04    /* bus released until completion */
  4949. + #define PHASE_CMDOUT    (WDCS_DRQ | WDCI_CMD)
  4950. + #define PHASE_DATAIN    (WDCS_DRQ | WDCI_IN)
  4951. + #define PHASE_DATAOUT   WDCS_DRQ
  4952. + #define PHASE_COMPLETED (WDCI_IN | WDCI_CMD)
  4953. + #define PHASE_ABORTED   0
  4954.   
  4955.   #ifdef _KERNEL
  4956.   /*
  4957.