home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / riscbsd / sources / patches / netbsd / atapidir_p / atapidir.patch
Encoding:
Text File  |  1996-06-14  |  65.9 KB  |  2,357 lines

  1. diff -c -r -N --exclude exp --exclude compile sys/atapi.orig/acd.c sys/atapi/acd.c
  2. *** sys/atapi.orig/acd.c    Thu Jan  1 01:00:00 1970
  3. --- sys/atapi/acd.c    Thu Jun 13 03:19:49 1996
  4. ***************
  5. *** 0 ****
  6. --- 1,1294 ----
  7. + /*
  8. +  * Copyright (c) 1996 Manuel Bouyer.  All rights reserved.
  9. +  *
  10. +  * Redistribution and use in source and binary forms, with or without
  11. +  * modification, are permitted provided that the following conditions
  12. +  * are met:
  13. +  * 1. Redistributions of source code must retain the above copyright
  14. +  *    notice, this list of conditions and the following disclaimer.
  15. +  * 2. Redistributions in binary form must reproduce the above copyright
  16. +  *    notice, this list of conditions and the following disclaimer in the
  17. +  *    documentation and/or other materials provided with the distribution.
  18. +  * 3. All advertising materials mentioning features or use of this software
  19. +  *    must display the following acknowledgement:
  20. +  *  This product includes software developed by Manuel Bouyer.
  21. +  * 4. The name of the author may not be used to endorse or promote products
  22. +  *    derived from this software without specific prior written permission.
  23. +  *
  24. +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  25. +  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  26. +  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  27. +  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  28. +  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  29. +  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  30. +  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31. +  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32. +  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  33. +  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. +  */
  35. + #include <sys/types.h>
  36. + #include <sys/param.h>
  37. + #include <sys/systm.h>
  38. + #include <sys/kernel.h>
  39. + #include <sys/conf.h>
  40. + #include <sys/file.h>
  41. + #include <sys/stat.h>
  42. + #include <sys/ioctl.h>
  43. + #include <sys/buf.h>
  44. + #include <sys/uio.h>
  45. + #include <sys/malloc.h>
  46. + #include <sys/errno.h>
  47. + #include <sys/device.h>
  48. + #include <sys/disklabel.h>
  49. + #include <sys/disk.h>
  50. + #include <sys/cdio.h>
  51. + #include <sys/proc.h>  
  52. + #include <atapi/atapilink.h>
  53. + #include <atapi/atapi.h>
  54. + #define    CDUNIT(z)            DISKUNIT(z)
  55. + #define    CDPART(z)            DISKPART(z)
  56. + #define    MAKECDDEV(maj, unit, part)    MAKEDISKDEV(maj, unit, part)
  57. + struct acd_softc {
  58. +     struct device sc_dev;
  59. +     struct disk sc_dk;
  60. +     int flags;
  61. + #define    CDF_LOCKED    0x01
  62. + #define    CDF_WANTED    0x02
  63. + #define    CDF_WLABEL    0x04        /* label is writable */
  64. + #define    CDF_LABELLING    0x08        /* writing label */
  65. +     struct at_dev_link *ad_link;    /* contains our drive number, etc ... */
  66. +     struct cd_parms {
  67. +         int blksize;
  68. +         u_long disksize;    /* total number sectors */
  69. +     } params;
  70. +     struct buf buf_queue;
  71. + };
  72. + int acdmatch __P((struct device *, void *, void *));
  73. + void acdattach __P((struct device *, struct device *, void *));
  74. + struct cfattach acd_ca = {
  75. +     sizeof(struct acd_softc), acdmatch, acdattach
  76. + };
  77. + struct cfdriver acd_cd = {
  78. +     NULL, "acd", DV_DISK
  79. + };
  80. + void acdgetdisklabel __P((struct acd_softc *));
  81. + int acd_get_parms __P((struct acd_softc *, int));
  82. + void acdstrategy __P((struct buf *));
  83. + void acdstart __P((struct acd_softc *));
  84. + int acd_pause __P((struct acd_softc *, int));
  85. + void    acdminphys __P((struct buf*));
  86. + u_long acd_size __P((struct acd_softc*, int));
  87. + int acddone __P((struct atapi_command_packet *));
  88. + int acd_reset __P((struct acd_softc *acd));
  89. + struct dkdriver acddkdriver = { acdstrategy };
  90. + int
  91. + acdmatch(parent, match, aux)
  92. +     struct device *parent;
  93. +     void *match, *aux;
  94. + {
  95. + /*    struct cfdata *cf = match;*/
  96. +     struct at_dev_link *sa = aux;
  97. + #ifdef ATAPI_DEBUG_PROBE
  98. +     printf("acdmatch: device %d\n",sa->id.config.device_type);
  99. + #endif
  100. +     if (sa->id.config.device_type == ATAPI_DEVICE_TYPE_CD) return 1;
  101. +     return 0;
  102. +     
  103. + }
  104. + /*
  105. +  * The routine called by the low level atapi routine when it discovers
  106. +  * A device suitable for this driver
  107. +  */
  108. + void
  109. + acdattach(parent, self, aux)
  110. +     struct device *parent, *self;
  111. +     void *aux;
  112. + {
  113. +     struct acd_softc *acd = (void *)self;
  114. +     struct at_dev_link *sa = aux;
  115. +     struct mode_sense cmd;
  116. +     struct cappage cap;
  117. +     sa->device_softc = acd;
  118. +     sa->start = acdstart;
  119. +     sa->done = acddone;
  120. +     sa->flags |= ADEV_REMOVABLE;
  121. +     sa->openings = 1;
  122. +     acd->ad_link = sa;
  123. +     /*
  124. +      * Initialize and attach the disk structure.
  125. +      */
  126. +     acd->sc_dk.dk_driver = &acddkdriver;
  127. +     acd->sc_dk.dk_name = acd->sc_dev.dv_xname;
  128. +     disk_attach(&acd->sc_dk);
  129. + #if !defined(i386) || defined(NEWCONFIG)
  130. +     dk_establish(&acd->sc_dk, &acd->sc_dev);   
  131. + #endif
  132. +     (void)atapi_test_unit_ready(sa, A_POLLED | A_SILENT); 
  133. +     delay(1000);
  134. +     (void)atapi_test_unit_ready(sa, A_POLLED | A_SILENT);
  135. +                                         /* To clear media change, etc ...*/
  136. +     bzero(&cmd, sizeof(cmd));
  137. +     cmd.operation_code = ATAPI_MODE_SENSE;
  138. +     cmd.page_code = CAP_PAGE;
  139. +     cmd.length[0] = sizeof (cap) >> 8;
  140. +     cmd.length[1] = sizeof (cap);
  141. +     if (atapi_exec_cmd(sa, &cmd , sizeof(cmd), &cap, sizeof(cap),
  142. +         B_READ, A_POLLED) != 0) {
  143. +         printf("atapi_exec_cmd failed\n");
  144. +         return;
  145. +     }
  146. +     switch (cap.medium_type) {
  147. +         case MDT_UNKNOWN:   printf ("medium type unknown");
  148. +                             break;
  149. +         case MDT_DATA_120:  printf ("120mm data disc ");
  150. +                             break;
  151. +         case MDT_AUDIO_120: printf ("120mm audio disc ");
  152. +                             break;
  153. +         case MDT_COMB_120:  printf ("120mm data/audio disc ");
  154. +                             break;
  155. +         case MDT_PHOTO_120: printf ("120mm photo disc ");
  156. +                             break;
  157. +         case MDT_DATA_80:   printf ("80mm data disc ");
  158. +                             break;
  159. +         case MDT_AUDIO_80:  printf ("80mm audio disc ");
  160. +                             break;
  161. +         case MDT_COMB_80:   printf ("80mm data/audio disc ");
  162. +                             break;
  163. +         case MDT_PHOTO_80:  printf ("80mm photo disc ");
  164. +                             break;
  165. +         case MDT_NO_DISC:   printf ("drive empty ");
  166. +                             break;
  167. +         case MDT_DOOR_OPEN: printf ("door open");
  168. +                             break;
  169. +         case MDT_FMT_ERROR: printf ("medium format error");
  170. +                             break;
  171. +         default:    printf ("unknown medium type=0x%x", cap.medium_type);
  172. +                     break;
  173. +     }
  174. +     printf("\n");
  175. + }
  176. + /*
  177. +  * Wait interruptibly for an exclusive lock.
  178. +  *
  179. +  * XXX
  180. +  * Several drivers do this; it should be abstracted and made MP-safe.
  181. +  */
  182. + int
  183. + acdlock(acd)
  184. +     struct acd_softc *acd;
  185. + {
  186. +     int error;
  187. +     while ((acd->flags & CDF_LOCKED) != 0) {
  188. +         acd->flags |= CDF_WANTED;
  189. +         if ((error = tsleep(acd, PRIBIO | PCATCH, "acdlck", 0)) != 0)
  190. +             return error;
  191. +     }
  192. +     acd->flags |= CDF_LOCKED;
  193. +     return 0;
  194. + }
  195. + /*
  196. +  * Unlock and wake up any waiters.
  197. +  */
  198. + void
  199. + acdunlock(acd)
  200. +     struct acd_softc *acd;
  201. + {
  202. +     acd->flags &= ~CDF_LOCKED;
  203. +     if ((acd->flags & CDF_WANTED) != 0) {
  204. +         acd->flags &= ~CDF_WANTED;
  205. +         wakeup(acd);
  206. +     }
  207. + }
  208. + /*
  209. +  * open the device. Make sure the partition info is a up-to-date as can be.
  210. +  */
  211. + int
  212. + acdopen(dev, flag, fmt)
  213. +     dev_t dev;
  214. +     int flag, fmt;
  215. + {
  216. +     struct acd_softc *acd;
  217. +     struct at_dev_link *ad_link;
  218. +     int unit, part;
  219. +     int error;
  220. + #ifdef ACD_DEBUG
  221. +     printf("acd: open\n");
  222. + #endif
  223. +     unit = CDUNIT(dev);
  224. +     if (unit >= acd_cd.cd_ndevs)
  225. +         return ENXIO;
  226. +     acd = acd_cd.cd_devs[unit];
  227. +     if (!acd)
  228. +         return ENXIO;
  229. +     ad_link = acd->ad_link;
  230. +     if ((error = atapi_test_unit_ready(ad_link,0)) != 0) {
  231. +         if (error != UNIT_ATTENTION) return EIO;
  232. +         if ((ad_link->flags & ADEV_OPEN) != 0 ) return EIO;
  233. +     }
  234. +     if ((error = acdlock(acd)))
  235. +         return error;
  236. +     if (acd->sc_dk.dk_openmask != 0) {
  237. +         /*
  238. +          * If any partition is open, but the disk has been invalidated,
  239. +          * disallow further opens.
  240. +          */
  241. +         if ((ad_link->flags & ADEV_MEDIA_LOADED) == 0) {
  242. +             error = EIO;
  243. +             goto bad3;
  244. +         }
  245. +     } else {
  246. +         ad_link->flags |= ADEV_OPEN;
  247. +         /* Lock the pack in. */
  248. +         if ((error = atapi_prevent(ad_link, PR_PREVENT)))
  249. +             goto bad;
  250. +         if ((ad_link->flags & ADEV_MEDIA_LOADED) == 0) {
  251. +             ad_link->flags |= ADEV_MEDIA_LOADED;
  252. +             /* Load the physical device parameters. */
  253. +             if (acd_get_parms(acd, 0) != 0) {
  254. +                 error = ENXIO;
  255. +                 goto bad2;
  256. +             }
  257. +             /* Fabricate a disk label. */
  258. +             acdgetdisklabel(acd);
  259. +         }
  260. +     }
  261. +     part = CDPART(dev);
  262. +     /* Check that the partition exists. */
  263. +     if (part != RAW_PART &&
  264. +         (part >= acd->sc_dk.dk_label->d_npartitions ||
  265. +          acd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
  266. +         error = ENXIO;
  267. +         goto bad;
  268. +     }
  269. +     /* Insure only one open at a time. */
  270. +     switch (fmt) {
  271. +     case S_IFCHR:
  272. +         acd->sc_dk.dk_copenmask |= (1 << part);
  273. +         break;
  274. +     case S_IFBLK:
  275. +         acd->sc_dk.dk_bopenmask |= (1 << part);
  276. +         break;
  277. +     }
  278. +     acd->sc_dk.dk_openmask = acd->sc_dk.dk_copenmask | acd->sc_dk.dk_bopenmask;
  279. + #ifdef ACD_DEBUG
  280. +     printf("open complete\n");
  281. + #endif
  282. +     acdunlock(acd);
  283. +     return 0;
  284. + bad2:
  285. +     ad_link->flags &= ~ADEV_MEDIA_LOADED;
  286. + bad:
  287. +     if (acd->sc_dk.dk_openmask == 0) {
  288. +         atapi_prevent(ad_link, PR_ALLOW);
  289. +         ad_link->flags &= ~ADEV_OPEN;
  290. +     }
  291. + bad3:
  292. +     acdunlock(acd);
  293. +     return error;
  294. + }
  295. + /*
  296. +  * close the device.. only called if we are the LAST
  297. +  * occurence of an open device
  298. +  */
  299. + int
  300. + acdclose(dev, flag, fmt)
  301. +     dev_t dev;
  302. +     int flag, fmt;
  303. + {
  304. +     struct acd_softc *acd = acd_cd.cd_devs[CDUNIT(dev)];
  305. +     int part = CDPART(dev);
  306. +     int error;
  307. +     if ((error = acdlock(acd)))
  308. +         return error;
  309. +     switch (fmt) {
  310. +     case S_IFCHR:
  311. +         acd->sc_dk.dk_copenmask &= ~(1 << part);
  312. +         break;
  313. +     case S_IFBLK:
  314. +         acd->sc_dk.dk_bopenmask &= ~(1 << part);
  315. +         break;
  316. +     }
  317. +     acd->sc_dk.dk_openmask = acd->sc_dk.dk_copenmask | acd->sc_dk.dk_bopenmask;
  318. +     if (acd->sc_dk.dk_openmask == 0) {
  319. +         /* XXXX Must wait for I/O to complete! */
  320. +         atapi_prevent(acd->ad_link, PR_ALLOW);
  321. +         acd->ad_link->flags &= ~ADEV_OPEN;
  322. +     }
  323. +     acdunlock(acd);
  324. +     return 0;
  325. + }
  326. + /*
  327. +  * Actually translate the requested transfer into one the physical driver can
  328. +  * understand.  The transfer is described by a buf and will include only one
  329. +  * physical transfer.
  330. +  */
  331. + void
  332. + acdstrategy(bp)
  333. +     struct buf *bp;
  334. + {
  335. +     struct acd_softc *acd = acd_cd.cd_devs[CDUNIT(bp->b_dev)];
  336. +     int opri;
  337. + #ifdef ACD_DEBUG
  338. +     printf("acdstrategy\n");
  339. + #endif
  340. +     /*
  341. +      * The transfer must be a whole number of blocks.
  342. +      */
  343. +     if ((bp->b_bcount % acd->sc_dk.dk_label->d_secsize) != 0) {
  344. +         bp->b_error = EINVAL;
  345. +         goto bad;
  346. +     }
  347. +     if ((bp->b_flags & (B_READ|B_WRITE)) == B_WRITE) {
  348. +         bp->b_error = EROFS;
  349. +         goto bad;
  350. +     }
  351. +     /*
  352. +      * If the device has been made invalid, error out
  353. +      * maybe the media changed
  354. +      */
  355. +     if ((acd->ad_link->flags & ADEV_MEDIA_LOADED) == 0) {
  356. +         bp->b_error = EIO;
  357. +         goto bad;
  358. +     }
  359. +     /*
  360. +      * If it's a null transfer, return immediately
  361. +      */
  362. +     if (bp->b_bcount == 0)
  363. +         goto done;
  364. +     /*
  365. +      * Do bounds checking, adjust transfer. if error, process.
  366. +      * If end of partition, just return.
  367. +      */
  368. +     if (CDPART(bp->b_dev) != RAW_PART &&
  369. +         bounds_check_with_label(bp, acd->sc_dk.dk_label,
  370. +         (acd->flags & (CDF_WLABEL|CDF_LABELLING)) != 0) <= 0)
  371. +         goto done;
  372. +     opri = splbio();
  373. +     /*
  374. +      * Place it in the queue of disk activities for this disk
  375. +      */
  376. +     disksort(&acd->buf_queue, bp);
  377. +     /*
  378. +      * Tell the device to get going on the transfer if it's
  379. +      * not doing anything, otherwise just wait for completion
  380. +      */
  381. +     acdstart(acd);
  382. +     splx(opri);
  383. +     return;
  384. + bad:
  385. +     bp->b_flags |= B_ERROR;
  386. + done:
  387. +     /*
  388. +      * Correctly set the buf to indicate a completed xfer
  389. +      */
  390. +     bp->b_resid = bp->b_bcount;
  391. +     biodone(bp);
  392. + }
  393. + /*
  394. +  * acdstart looks to see if there is a buf waiting for the device
  395. +  * and that the device is not already busy. If both are true,
  396. +  * It deques the buf and creates a atapi command to perform the
  397. +  * transfer in the buf. The transfer request will call atapi_done
  398. +  * on completion, which will in turn call this routine again
  399. +  * so that the next queued transfer is performed.
  400. +  * The bufs are queued by the strategy routine (cdstrategy)
  401. +  *
  402. +  * This routine is also called after other non-queued requests
  403. +  * have been made of the atapi driver, to ensure that the queue
  404. +  * continues to be drained.
  405. +  *
  406. +  * must be called at the correct (highish) spl level
  407. +  * cdstart() is called at splbio from cdstrategy and atapi_done
  408. +  */
  409. + void
  410. + acdstart(acd)
  411. +     struct acd_softc *acd;
  412. + {
  413. +     struct at_dev_link *ad_link;
  414. +     struct buf *bp = 0;
  415. +     struct buf *dp;
  416. +     struct read cmd;
  417. +     u_int32_t blkno, nblks;
  418. +     struct partition *p;
  419. + #ifdef ACD_DEBUG
  420. +     printf("acd: acdstart\n");
  421. +     if (acd == NULL) {
  422. +         printf("acdstart: null acd\n");
  423. +         return;
  424. +     }
  425. + #endif
  426. +         
  427. +     ad_link = acd->ad_link;
  428. + #ifdef ACD_DEBUG
  429. +     if (ad_link == NULL) {
  430. +         printf("acdstart: null ad_link\n");
  431. +         return;
  432. +     }
  433. + #endif
  434. +     /*
  435. +      * Check if the device has room for another command
  436. +      */
  437. +     while (ad_link->openings >0 ) {
  438. +         /*
  439. +          * there is excess capacity, but a special waits
  440. +          * It'll need the adapter as soon as we clear out of the
  441. +          * way and let it run (user level wait).
  442. +          */
  443. +         if (ad_link->flags & ADEV_WAITING) {
  444. + #ifdef ATAPI_DEBUG
  445. +             printf("acdstart: waking up\n");
  446. + #endif
  447. +             ad_link->flags &= ~ADEV_WAITING;
  448. +             wakeup((caddr_t)ad_link);
  449. +             return;
  450. +         }
  451. +         
  452. +         /*
  453. +          * See if there is a buf with work for us to do..
  454. +          */
  455. +         dp = &acd->buf_queue;
  456. + #ifdef ACD_DEBUG
  457. +         if (dp == NULL) {
  458. +             printf("acdstart: null dp\n");
  459. +             return;
  460. +         }
  461. + #endif
  462. +         if ((bp = dp->b_actf) == NULL)    /* yes, an assign */
  463. +             return;
  464. + #ifdef ACD_DEBUG
  465. +         printf("acdstart: a buf\n");
  466. + #endif
  467. +         dp->b_actf = bp->b_actf;
  468. +         /*
  469. +          * If the device has become invalid, abort all the
  470. +          * reads and writes until all files have been closed and
  471. +          * re-opened
  472. +          */
  473. +         if ((ad_link->flags & ADEV_MEDIA_LOADED) == 0) {
  474. +             bp->b_error = EIO;
  475. +             bp->b_flags |= B_ERROR;
  476. +             biodone(bp);
  477. +             continue;
  478. +         }
  479. +         /*
  480. +          *
  481. +          * First, translate the block to absolute and put it in terms
  482. +          * of the logical blocksize of the device.
  483. +          */
  484. +         blkno =
  485. +             bp->b_blkno / (acd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
  486. +         if (CDPART(bp->b_dev) != RAW_PART) {
  487. +             p = &acd->sc_dk.dk_label->d_partitions[CDPART(bp->b_dev)];
  488. +             blkno += p->p_offset;
  489. +         }
  490. +         nblks = howmany(bp->b_bcount, acd->sc_dk.dk_label->d_secsize);
  491. + #ifdef ACD_DEBUG
  492. +         printf("acdstart: blkno %d nblk %d\n",blkno, nblks);
  493. + #endif
  494. +         /*
  495. +          *  Fill out the atapi command
  496. +          */
  497. +         bzero(&cmd, sizeof(cmd));
  498. +         cmd.operation_code = ATAPI_READ;
  499. +         cmd.lba[0] = (blkno >> 24) & 0xff;
  500. +         cmd.lba[1] = (blkno >> 16) & 0xff;
  501. +         cmd.lba[2] = (blkno >> 8) & 0xff;
  502. +         cmd.lba[3] = blkno & 0xff;
  503. +         cmd.length[0] = (nblks >> 8) & 0xff;
  504. +         cmd.length[1] = nblks & 0xff;
  505. +         /* Instrumentation. */
  506. +         disk_busy(&acd->sc_dk);
  507. +         /*
  508. +          * Call the routine that chats with the adapter.
  509. +          * Note: we cannot sleep as we may be an interrupt
  510. +          */
  511. +          if (atapi_exec_io(ad_link, &cmd, sizeof(cmd), bp, A_NOSLEEP))
  512. +             printf("%s: not queued", acd->sc_dev.dv_xname);
  513. +     }
  514. + }
  515. + int
  516. + acdread(dev, uio)
  517. +     dev_t dev;
  518. +     struct uio *uio;
  519. + {
  520. +     return (physio(acdstrategy, NULL, dev, B_READ,
  521. +                acdminphys, uio));
  522. + }
  523. + int
  524. + acdwrite(dev, uio)
  525. +     dev_t dev;
  526. +     struct uio *uio;
  527. + {
  528. +     return (physio(acdstrategy, NULL, dev, B_WRITE,
  529. +                acdminphys, uio));
  530. + }
  531. + /*
  532. +  * Perform special action on behalf of the user.
  533. +  * Knows about the internals of this device
  534. +  */
  535. + int
  536. + acdioctl(dev, cmd, addr, flag, p)
  537. +     dev_t dev;
  538. +     u_long cmd;
  539. +     caddr_t addr;
  540. +     int flag;
  541. +     struct proc *p;
  542. + {
  543. +     struct acd_softc *acd = acd_cd.cd_devs[CDUNIT(dev)];
  544. +     int error;
  545. +     /*
  546. +      * If the device is not valid.. abandon ship
  547. +      */
  548. +     if ((acd->ad_link->flags & ADEV_MEDIA_LOADED) == 0)
  549. +         return EIO;
  550. +     switch (cmd) {
  551. +     case DIOCGDINFO:
  552. +         *(struct disklabel *)addr = *acd->sc_dk.dk_label;
  553. +         return 0;
  554. +     case DIOCGPART:
  555. +         ((struct partinfo *)addr)->disklab = acd->sc_dk.dk_label;
  556. +         ((struct partinfo *)addr)->part =
  557. +             &acd->sc_dk.dk_label->d_partitions[CDPART(dev)];
  558. +         return 0;
  559. +     case DIOCWDINFO:
  560. +     case DIOCSDINFO:
  561. +         if ((flag & FWRITE) == 0)
  562. +             return EBADF;
  563. +         if ((error = acdlock(acd)))
  564. +             return error;
  565. +         acd->flags |= CDF_LABELLING;
  566. +         error = setdisklabel(acd->sc_dk.dk_label,
  567. +             (struct disklabel *)addr, /*acd->sc_dk.dk_openmask : */0,
  568. +             acd->sc_dk.dk_cpulabel);
  569. +         if (error == 0) {
  570. +         }
  571. +         acd->flags &= ~CDF_LABELLING;
  572. +         acdunlock(acd);
  573. +         return error;
  574. +     case DIOCWLABEL:
  575. +         return EBADF;
  576. +     case CDIOCPLAYTRACKS:
  577. + #ifdef notyet
  578. +         {
  579. +         struct ioc_play_track *args = (struct ioc_play_track *)addr;
  580. +         struct acd_mode_data data;
  581. +         if (error = acd_get_mode(acd, &data, AUDIO_PAGE))
  582. +             return error;
  583. +         data.page.audio.flags &= ~CD_PA_SOTC;
  584. +         data.page.audio.flags |= CD_PA_IMMED;
  585. +         if (error = acd_set_mode(acd, &data))
  586. +             return error;
  587. +         return acd_play_tracks(acd, args->start_track, args->start_index,
  588. +             args->end_track, args->end_index);
  589. +     }
  590. + #else
  591. +     return ENOTTY;
  592. + #endif
  593. +     case CDIOCPLAYMSF:
  594. + #ifdef notyet
  595. +         {
  596. +         struct ioc_play_msf *args
  597. +         = (struct ioc_play_msf *)addr;
  598. +         struct cd_mode_data data;
  599. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  600. +             return error;
  601. +         data.page.audio.flags &= ~CD_PA_SOTC;
  602. +         data.page.audio.flags |= CD_PA_IMMED;
  603. +         if (error = cd_set_mode(cd, &data))
  604. +             return error;
  605. +         return cd_play_msf(cd, args->start_m, args->start_s,
  606. +             args->start_f, args->end_m, args->end_s, args->end_f);
  607. +     }
  608. + #else
  609. +     return ENOTTY; 
  610. + #endif
  611. +     case CDIOCPLAYBLOCKS:
  612. + #ifdef notyet
  613. +     {
  614. +         struct ioc_play_blocks *args
  615. +         = (struct ioc_play_blocks *)addr;
  616. +         struct cd_mode_data data;
  617. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  618. +             return error;
  619. +         data.page.audio.flags &= ~CD_PA_SOTC;
  620. +         data.page.audio.flags |= CD_PA_IMMED;
  621. +         if (error = cd_set_mode(cd, &data))
  622. +             return error;
  623. +         return cd_play(cd, args->blk, args->len);
  624. +     }
  625. + #else
  626. +     return ENOTTY; 
  627. + #endif
  628. +     case CDIOCREADSUBCHANNEL:
  629. + #ifdef notyet 
  630. +     {
  631. +         struct ioc_read_subchannel *args
  632. +         = (struct ioc_read_subchannel *)addr;
  633. +         struct cd_sub_channel_info data;
  634. +         int len = args->data_len;
  635. +         if (len > sizeof(data) ||
  636. +             len < sizeof(struct cd_sub_channel_header))
  637. +             return EINVAL;
  638. +         if (error = cd_read_subchannel(cd, args->address_format,
  639. +             args->data_format, args->track, &data, len))
  640. +             return error;
  641. +         len = min(len, ((data.header.data_len[0] << 8) +
  642. +             data.header.data_len[1] +
  643. +             sizeof(struct cd_sub_channel_header)));
  644. +         return copyout(&data, args->data, len);
  645. +     }
  646. + #else
  647. +     return ENOTTY; 
  648. + #endif
  649. +     case CDIOREADTOCHEADER:
  650. + #ifdef notyet
  651. +     {
  652. +         struct ioc_toc_header th;
  653. +         if (error = cd_read_toc(cd, 0, 0, &th, sizeof(th)))
  654. +             return error;
  655. +         th.len = ntohs(th.len);
  656. +         bcopy(&th, addr, sizeof(th));
  657. +         return 0;
  658. +     }
  659. + #else
  660. +     return ENOTTY; 
  661. + #endif
  662. +     case CDIOREADTOCENTRYS:
  663. + #ifdef notyet
  664. +     {
  665. +         struct cd_toc {
  666. +             struct ioc_toc_header header;
  667. +             struct cd_toc_entry entries[65];
  668. +         } data;
  669. +         struct ioc_read_toc_entry *te =
  670. +         (struct ioc_read_toc_entry *)addr;
  671. +         struct ioc_toc_header *th;
  672. +         int len = te->data_len;
  673. +         th = &data.header;
  674. +         if (len > sizeof(data.entries) ||
  675. +             len < sizeof(struct cd_toc_entry))
  676. +             return EINVAL;
  677. +         if (error = cd_read_toc(cd, te->address_format,
  678. +             te->starting_track, (struct cd_toc_entry *)&data,
  679. +             len + sizeof(struct ioc_toc_header)))
  680. +             return error;
  681. +         len = min(len, ntohs(th->len) - (sizeof(th->starting_track) +
  682. +             sizeof(th->ending_track)));
  683. +         return copyout(data.entries, te->data, len);
  684. +     }
  685. + #else
  686. +     return ENOTTY; 
  687. + #endif
  688. +     case CDIOCSETPATCH:
  689. + #ifdef notyet
  690. + {
  691. +         struct ioc_patch *arg = (struct ioc_patch *)addr;
  692. +         struct cd_mode_data data;
  693. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  694. +             return error;
  695. +         data.page.audio.port[LEFT_PORT].channels = arg->patch[0];
  696. +         data.page.audio.port[RIGHT_PORT].channels = arg->patch[1];
  697. +         data.page.audio.port[2].channels = arg->patch[2];
  698. +         data.page.audio.port[3].channels = arg->patch[3];
  699. +         return cd_set_mode(cd, &data);
  700. +     }
  701. + #else
  702. +     return ENOTTY; 
  703. + #endif
  704. +     case CDIOCGETVOL:
  705. + #ifdef notyet
  706. +     {
  707. +         struct ioc_vol *arg = (struct ioc_vol *)addr;
  708. +         struct cd_mode_data data;
  709. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  710. +             return error;
  711. +         arg->vol[LEFT_PORT] = data.page.audio.port[LEFT_PORT].volume;
  712. +         arg->vol[RIGHT_PORT] = data.page.audio.port[RIGHT_PORT].volume;
  713. +         arg->vol[2] = data.page.audio.port[2].volume;
  714. +         arg->vol[3] = data.page.audio.port[3].volume;
  715. +         return 0;
  716. +     }
  717. + #else
  718. +     return ENOTTY; 
  719. + #endif
  720. +     case CDIOCSETVOL:
  721. + #ifdef notyet
  722. + {
  723. +         struct ioc_vol *arg = (struct ioc_vol *)addr;
  724. +         struct cd_mode_data data;
  725. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  726. +             return error;
  727. +         data.page.audio.port[LEFT_PORT].channels = CHANNEL_0;
  728. +         data.page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT];
  729. +         data.page.audio.port[RIGHT_PORT].channels = CHANNEL_1;
  730. +         data.page.audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT];
  731. +         data.page.audio.port[2].volume = arg->vol[2];
  732. +         data.page.audio.port[3].volume = arg->vol[3];
  733. +         return cd_set_mode(cd, &data);
  734. +     }
  735. + #else
  736. +     return ENOTTY; 
  737. + #endif
  738. +     case CDIOCSETMONO:
  739. + #ifdef notyet
  740. +     {
  741. +         struct ioc_vol *arg = (struct ioc_vol *)addr;
  742. +         struct cd_mode_data data;
  743. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  744. +             return error;
  745. +         data.page.audio.port[LEFT_PORT].channels =
  746. +             LEFT_CHANNEL | RIGHT_CHANNEL | 4 | 8;
  747. +         data.page.audio.port[RIGHT_PORT].channels =
  748. +             LEFT_CHANNEL | RIGHT_CHANNEL;
  749. +         data.page.audio.port[2].channels = 0;
  750. +         data.page.audio.port[3].channels = 0;
  751. +         return cd_set_mode(cd, &data);
  752. +     }
  753. + #else
  754. +     return ENOTTY; 
  755. + #endif
  756. +     case CDIOCSETSTEREO:
  757. + #ifdef notyet
  758. +     {
  759. +         struct ioc_vol *arg = (struct ioc_vol *)addr;
  760. +         struct cd_mode_data data;
  761. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  762. +             return error;
  763. +         data.page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL;
  764. +         data.page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL;
  765. +         data.page.audio.port[2].channels = 0;
  766. +         data.page.audio.port[3].channels = 0;
  767. +         return cd_set_mode(cd, &data);
  768. +     }
  769. + #else
  770. +     return ENOTTY; 
  771. + #endif
  772. +     case CDIOCSETMUTE:
  773. + #ifdef notyet
  774. + {
  775. +         struct ioc_vol *arg = (struct ioc_vol *)addr;
  776. +         struct cd_mode_data data;
  777. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  778. +             return error;
  779. +         data.page.audio.port[LEFT_PORT].channels = 0;
  780. +         data.page.audio.port[RIGHT_PORT].channels = 0;
  781. +         data.page.audio.port[2].channels = 0;
  782. +         data.page.audio.port[3].channels = 0;
  783. +         return cd_set_mode(cd, &data);
  784. +     }
  785. + #else
  786. +     return ENOTTY; 
  787. + #endif
  788. +     case CDIOCSETLEFT:
  789. + #ifdef notyet
  790. + {
  791. +         struct ioc_vol *arg = (struct ioc_vol *)addr;
  792. +         struct cd_mode_data data;
  793. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  794. +             return error;
  795. +         data.page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL;
  796. +         data.page.audio.port[RIGHT_PORT].channels = LEFT_CHANNEL;
  797. +         data.page.audio.port[2].channels = 0;
  798. +         data.page.audio.port[3].channels = 0;
  799. +         return cd_set_mode(cd, &data);
  800. +     }
  801. + #else
  802. +     return ENOTTY; 
  803. + #endif
  804. +     case CDIOCSETRIGHT:
  805. + #ifdef notyet
  806. + {
  807. +         struct ioc_vol *arg = (struct ioc_vol *)addr;
  808. +         struct cd_mode_data data;
  809. +         if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
  810. +             return error;
  811. +         data.page.audio.port[LEFT_PORT].channels = RIGHT_CHANNEL;
  812. +         data.page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL;
  813. +         data.page.audio.port[2].channels = 0;
  814. +         data.page.audio.port[3].channels = 0;
  815. +         return cd_set_mode(cd, &data);
  816. +     }
  817. + #else
  818. +     return ENOTTY; 
  819. + #endif
  820. +     case CDIOCRESUME:
  821. +         return acd_pause(acd, 1);
  822. +     case CDIOCPAUSE:
  823. +         return acd_pause(acd, 0);
  824. +     case CDIOCSTART:
  825. +         return atapi_start_stop(acd->ad_link, SSS_START, 0);
  826. +     case CDIOCSTOP:
  827. +         return atapi_start_stop(acd->ad_link, SSS_STOP, 0);
  828. +     case CDIOCEJECT: /* FALLTHROUGH */
  829. +     case DIOCEJECT:
  830. +         return atapi_start_stop(acd->ad_link, SSS_STOP|SSS_LOEJ, 0);
  831. +     case CDIOCALLOW:
  832. +         return atapi_prevent(acd->ad_link, PR_ALLOW);
  833. +     case CDIOCPREVENT:
  834. +         return atapi_prevent(acd->ad_link, PR_PREVENT);
  835. +     case DIOCLOCK:
  836. +         return atapi_prevent(acd->ad_link,
  837. +             (*(int *)addr) ? PR_PREVENT : PR_ALLOW);
  838. +     case CDIOCRESET:
  839. +         return acd_reset(acd);
  840. +     default:
  841. +         return ENOTTY;
  842. +     }
  843. + #ifdef DIAGNOSTIC
  844. +     panic("cdioctl: impossible");
  845. + #endif
  846. + }
  847. + /*
  848. +  * Load the label information on the named device
  849. +  * Actually fabricate a disklabel
  850. +  *
  851. +  * EVENTUALLY take information about different
  852. +  * data tracks from the TOC and put it in the disklabel
  853. +  */
  854. + void
  855. + acdgetdisklabel(acd)
  856. +     struct acd_softc *acd;
  857. + {
  858. +     struct disklabel *lp = acd->sc_dk.dk_label;
  859. +     bzero(lp, sizeof(struct disklabel));
  860. +     bzero(acd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
  861. + /*    lp->d_secsize = acd->params.blksize;*/ /* XXX */
  862. +     lp->d_secsize = 2048;
  863. +     lp->d_ntracks = 1;
  864. +     lp->d_nsectors = 100;
  865. +     lp->d_ncylinders = (acd->params.disksize / 100) + 1;
  866. +     lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
  867. +     strncpy(lp->d_typename, "ATAPI CD-ROM", 16);
  868. +     lp->d_type = DTYPE_SCSI; /* XXX */
  869. +     strncpy(lp->d_packname, "fictitious", 16);
  870. +     lp->d_secperunit = acd->params.disksize;
  871. +     lp->d_rpm = 300;
  872. +     lp->d_interleave = 1;
  873. +     lp->d_flags = D_REMOVABLE;
  874. +     lp->d_partitions[0].p_offset = 0;
  875. +     lp->d_partitions[0].p_size =
  876. +         lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
  877. +     lp->d_partitions[0].p_fstype = FS_ISO9660;
  878. +     lp->d_partitions[RAW_PART].p_offset = 0;
  879. +     lp->d_partitions[RAW_PART].p_size =
  880. +         lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
  881. +     lp->d_partitions[RAW_PART].p_fstype = FS_ISO9660;
  882. +     lp->d_npartitions = RAW_PART + 1;
  883. +     lp->d_magic = DISKMAGIC;
  884. +     lp->d_magic2 = DISKMAGIC;
  885. +     lp->d_checksum = dkcksum(lp);
  886. + }
  887. + /*
  888. +  * Find out from the device what it's capacity is
  889. +  */
  890. + u_long
  891. + acd_size(cd, flags)
  892. +     struct acd_softc *cd;
  893. +     int flags;
  894. + {
  895. +     struct read_cd_capacity_data rdcap;
  896. +     struct read_cd_capacity cmd;
  897. +     u_long blksize;
  898. +     u_long size=0;
  899. +     /*
  900. +      * make up a atapi command and ask the atapi driver to do
  901. +      * it for you.
  902. +      */
  903. +     bzero(&cmd, sizeof(cmd));
  904. +     cmd.operation_code = ATAPI_READ_CD_CAPACITY;
  905. +     cmd.len = sizeof(rdcap);
  906. +     /*
  907. +      * If the command works, interpret the result as a 4 byte
  908. +      * number of blocks and a blocksize
  909. +      */
  910. +     if (atapi_exec_cmd(cd->ad_link, &cmd , sizeof(cmd),
  911. +         &rdcap, sizeof(rdcap), B_READ, 0) != 0) {
  912. + #ifdef ATAPI_DEBUG
  913. +         printf("ATAPI_READ_CD_CAPACITY failed\n");
  914. + #endif
  915. +         return 0;
  916. +     }
  917. +     blksize = ntohl(rdcap.blksize);
  918. +     if (blksize < 512)
  919. +         blksize = 2048;    /* some drives lie ! */
  920. +     cd->params.blksize = blksize;
  921. +     size = ntohl(rdcap.size);
  922. +     if (size < 100)
  923. +         size = 400000;    /* ditto */
  924. +     cd->params.disksize = size;
  925. + #ifdef ATAPI_DEBUG
  926. +     printf("acd_size: %ld %ld\n",blksize,size);
  927. + #endif
  928. +     return size;
  929. + }
  930. + #ifdef notyet
  931. + /*
  932. +  * Get the requested page into the buffer given
  933. +  */
  934. + int
  935. + cd_get_mode(cd, data, page)
  936. +     struct acd_softc *cd;
  937. +     struct cd_mode_data *data;
  938. +     int page;
  939. + {
  940. +     struct scsi_mode_sense scsi_cmd;
  941. +     int error;
  942. +     bzero(&scsi_cmd, sizeof(scsi_cmd));
  943. +     bzero(data, sizeof(*data));
  944. +     scsi_cmd.opcode = MODE_SENSE;
  945. +     scsi_cmd.page = page;
  946. +     scsi_cmd.length = sizeof(*data) & 0xff;
  947. +     return scsi_scsi_cmd(cd->ad_link, (struct scsi_generic *)&scsi_cmd,
  948. +         sizeof(scsi_cmd), (u_char *)data, sizeof(*data), CDRETRIES, 20000,
  949. +         NULL, SCSI_DATA_IN);
  950. + }
  951. + /*
  952. +  * Get the requested page into the buffer given
  953. +  */
  954. + int
  955. + cd_set_mode(cd, data)
  956. +     struct acd_softc *cd;
  957. +     struct cd_mode_data *data;
  958. + {
  959. +     struct scsi_mode_select scsi_cmd;
  960. +     bzero(&scsi_cmd, sizeof(scsi_cmd));
  961. +     scsi_cmd.opcode = MODE_SELECT;
  962. +     scsi_cmd.byte2 |= SMS_PF;
  963. +     scsi_cmd.length = sizeof(*data) & 0xff;
  964. +     data->header.data_length = 0;
  965. +     return scsi_scsi_cmd(cd->ad_link, (struct scsi_generic *)&scsi_cmd,
  966. +         sizeof(scsi_cmd), (u_char *)data, sizeof(*data), CDRETRIES, 20000,
  967. +         NULL, SCSI_DATA_OUT);
  968. + }
  969. + /*
  970. +  * Get scsi driver to send a "start playing" command
  971. +  */
  972. + int
  973. + cd_play(cd, blkno, nblks)
  974. +     struct acd_softc *cd;
  975. +     int blkno, nblks;
  976. + {
  977. +     struct scsi_play scsi_cmd;
  978. +     bzero(&scsi_cmd, sizeof(scsi_cmd));
  979. +     scsi_cmd.opcode = PLAY;
  980. +     scsi_cmd.blk_addr[0] = (blkno >> 24) & 0xff;
  981. +     scsi_cmd.blk_addr[1] = (blkno >> 16) & 0xff;
  982. +     scsi_cmd.blk_addr[2] = (blkno >> 8) & 0xff;
  983. +     scsi_cmd.blk_addr[3] = blkno & 0xff;
  984. +     scsi_cmd.xfer_len[0] = (nblks >> 8) & 0xff;
  985. +     scsi_cmd.xfer_len[1] = nblks & 0xff;
  986. +     return scsi_scsi_cmd(cd->ad_link, (struct scsi_generic *)&scsi_cmd,
  987. +         sizeof(scsi_cmd), 0, 0, CDRETRIES, 200000, NULL, 0);
  988. + }
  989. + /*
  990. +  * Get scsi driver to send a "start playing" command
  991. +  */
  992. + int
  993. + cd_play_big(cd, blkno, nblks)
  994. +     struct acd_softc *cd;
  995. +     int blkno, nblks;
  996. + {
  997. +     struct scsi_play_big scsi_cmd;
  998. +     bzero(&scsi_cmd, sizeof(scsi_cmd));
  999. +     scsi_cmd.opcode = PLAY_BIG;
  1000. +     scsi_cmd.blk_addr[0] = (blkno >> 24) & 0xff;
  1001. +     scsi_cmd.blk_addr[1] = (blkno >> 16) & 0xff;
  1002. +     scsi_cmd.blk_addr[2] = (blkno >> 8) & 0xff;
  1003. +     scsi_cmd.blk_addr[3] = blkno & 0xff;
  1004. +     scsi_cmd.xfer_len[0] = (nblks >> 24) & 0xff;
  1005. +     scsi_cmd.xfer_len[1] = (nblks >> 16) & 0xff;
  1006. +     scsi_cmd.xfer_len[2] = (nblks >> 8) & 0xff;
  1007. +     scsi_cmd.xfer_len[3] = nblks & 0xff;
  1008. +     return scsi_scsi_cmd(cd->ad_link, (struct scsi_generic *)&scsi_cmd,
  1009. +         sizeof(scsi_cmd), 0, 0, CDRETRIES, 20000, NULL, 0);
  1010. + }
  1011. + /*
  1012. +  * Get scsi driver to send a "start playing" command
  1013. +  */
  1014. + int
  1015. + cd_play_tracks(cd, strack, sindex, etrack, eindex)
  1016. +     struct acd_softc *cd;
  1017. +     int strack, sindex, etrack, eindex;
  1018. + {
  1019. +     struct scsi_play_track scsi_cmd;
  1020. +     bzero(&scsi_cmd, sizeof(scsi_cmd));
  1021. +     scsi_cmd.opcode = PLAY_TRACK;
  1022. +     scsi_cmd.start_track = strack;
  1023. +     scsi_cmd.start_index = sindex;
  1024. +     scsi_cmd.end_track = etrack;
  1025. +     scsi_cmd.end_index = eindex;
  1026. +     return scsi_scsi_cmd(cd->ad_link, (struct scsi_generic *)&scsi_cmd,
  1027. +         sizeof(scsi_cmd), 0, 0, CDRETRIES, 20000, NULL, 0);
  1028. + }
  1029. + /*
  1030. +  * Get scsi driver to send a "play msf" command
  1031. +  */
  1032. + int
  1033. + cd_play_msf(cd, startm, starts, startf, endm, ends, endf)
  1034. +     struct acd_softc *cd;
  1035. +     int startm, starts, startf, endm, ends, endf;
  1036. + {
  1037. +     struct scsi_play_msf scsi_cmd;
  1038. +     bzero(&scsi_cmd, sizeof(scsi_cmd));
  1039. +     scsi_cmd.opcode = PLAY_MSF;
  1040. +     scsi_cmd.start_m = startm;
  1041. +     scsi_cmd.start_s = starts;
  1042. +     scsi_cmd.start_f = startf;
  1043. +     scsi_cmd.end_m = endm;
  1044. +     scsi_cmd.end_s = ends;
  1045. +     scsi_cmd.end_f = endf;
  1046. +     return scsi_scsi_cmd(cd->ad_link, (struct scsi_generic *)&scsi_cmd,
  1047. +         sizeof(scsi_cmd), 0, 0, CDRETRIES, 2000, NULL, 0);
  1048. + }
  1049. + #endif  /* notyet */
  1050. + /*
  1051. +  * Get atapi driver to send a "start up" command
  1052. +  */
  1053. + int
  1054. + acd_pause(acd, go)
  1055. +     struct acd_softc *acd;
  1056. +     int go;
  1057. + {
  1058. +     struct pause_resume cmd;
  1059. +     bzero(&cmd, sizeof(cmd));
  1060. +     cmd.operation_code = ATAPI_PAUSE_RESUME;
  1061. +     cmd.resume = go;
  1062. +     return atapi_exec_cmd(acd->ad_link, &cmd , sizeof(cmd), 0, 0, 0, 0);
  1063. + }
  1064. + /*
  1065. +  * Get atapi driver to send a "RESET" command
  1066. +  */
  1067. + int
  1068. + acd_reset(acd)
  1069. +     struct acd_softc *acd;
  1070. + {
  1071. + #ifdef notyet    
  1072. +     return atapi_soft_reset(acd->ad_link);
  1073. + #else
  1074. +      return 0;
  1075. + #endif
  1076. + }
  1077. + #ifdef notyet
  1078. + /*
  1079. +  * Read subchannel
  1080. +  */
  1081. + int
  1082. + cd_read_subchannel(cd, mode, format, track, data, len)
  1083. +     struct acd_softc *cd;
  1084. +     int mode, format, len;
  1085. +     struct cd_sub_channel_info *data;
  1086. + {
  1087. +     struct scsi_read_subchannel scsi_cmd;
  1088. +     bzero(&scsi_cmd, sizeof(scsi_cmd));
  1089. +     scsi_cmd.opcode = READ_SUBCHANNEL;
  1090. +     if (mode == CD_MSF_FORMAT)
  1091. +         scsi_cmd.byte2 |= CD_MSF;
  1092. +     scsi_cmd.byte3 = SRS_SUBQ;
  1093. +     scsi_cmd.subchan_format = format;
  1094. +     scsi_cmd.track = track;
  1095. +     scsi_cmd.data_len[0] = (len >> 8) & 0xff;
  1096. +     scsi_cmd.data_len[1] = len & 0xff;
  1097. +     return scsi_scsi_cmd(cd->ad_link, (struct scsi_generic *)&scsi_cmd,
  1098. +         sizeof(struct scsi_read_subchannel), (u_char *)data, len,
  1099. +         CDRETRIES, 5000, NULL, SCSI_DATA_IN);
  1100. + }
  1101. + /*
  1102. +  * Read table of contents
  1103. +  */
  1104. + int
  1105. + cd_read_toc(cd, mode, start, data, len)
  1106. +     struct acd_softc *cd;
  1107. +     int mode, start, len;
  1108. +     struct cd_toc_entry *data;
  1109. + {
  1110. +     struct scsi_read_toc scsi_cmd;
  1111. +     int ntoc;
  1112. +     bzero(&scsi_cmd, sizeof(scsi_cmd));
  1113. +     /*if (len!=sizeof(struct ioc_toc_header))
  1114. +      * ntoc=((len)-sizeof(struct ioc_toc_header))/sizeof(struct cd_toc_entry);
  1115. +      * else */
  1116. +     ntoc = len;
  1117. +     scsi_cmd.opcode = READ_TOC;
  1118. +     if (mode == CD_MSF_FORMAT)
  1119. +         scsi_cmd.byte2 |= CD_MSF;
  1120. +     scsi_cmd.from_track = start;
  1121. +     scsi_cmd.data_len[0] = (ntoc >> 8) & 0xff;
  1122. +     scsi_cmd.data_len[1] = ntoc & 0xff;
  1123. +     return scsi_scsi_cmd(cd->ad_link, (struct scsi_generic *)&scsi_cmd,
  1124. +         sizeof(struct scsi_read_toc), (u_char *)data, len, CDRETRIES,
  1125. +         5000, NULL, SCSI_DATA_IN);
  1126. + }
  1127. + #endif /* notyet */
  1128. + /*
  1129. +  * Get the atapi driver to send a full inquiry to the device and use the
  1130. +  * results to fill out the disk parameter structure.
  1131. +  */
  1132. + int
  1133. + acd_get_parms(acd, flags)
  1134. +     struct acd_softc *acd;
  1135. +     int flags;
  1136. + {
  1137. +     /*
  1138. +      * give a number of sectors so that sec * trks * cyls
  1139. +      * is <= disk_size
  1140. +      */
  1141. +     if (acd_size(acd, flags) == 0)
  1142. +         return ENXIO;
  1143. +     return 0;
  1144. + }
  1145. + int
  1146. + acdsize(dev)
  1147. +     dev_t dev;
  1148. + {
  1149. +     /* CD-ROMs are read-only. */
  1150. +     return -1;
  1151. + }
  1152. + void acdminphys(bp)
  1153. + struct buf *bp;
  1154. + {
  1155. +     minphys(bp);
  1156. + }
  1157. + int
  1158. + acddump(dev, blkno, va, size)
  1159. +     dev_t dev;
  1160. +     daddr_t blkno;
  1161. +     caddr_t va;
  1162. +     size_t size;
  1163. + {
  1164. +     /* Not implemented. */
  1165. +     return ENXIO;
  1166. + }
  1167. + int
  1168. + acddone(acp)
  1169. + struct atapi_command_packet *acp;
  1170. + {
  1171. +     struct at_dev_link *ad_link = acp->ad_link;
  1172. +     struct acd_softc *acd = ad_link->device_softc;
  1173. +     if (acp->bp != NULL)
  1174. +         disk_unbusy(&acd->sc_dk, (acp->bp->b_bcount - acp->bp->b_resid));
  1175. +     return (0);     
  1176. + }   
  1177. diff -c -r -N --exclude exp --exclude compile sys/atapi.orig/atapi.h sys/atapi/atapi.h
  1178. *** sys/atapi.orig/atapi.h    Thu Jan  1 01:00:00 1970
  1179. --- sys/atapi/atapi.h    Thu Jun 13 03:19:49 1996
  1180. ***************
  1181. *** 0 ****
  1182. --- 1,244 ----
  1183. + /*
  1184. +  * Copyright (c) 1996 Manuel Bouyer.  All rights reserved.
  1185. +  *
  1186. +  * Redistribution and use in source and binary forms, with or without
  1187. +  * modification, are permitted provided that the following conditions
  1188. +  * are met:
  1189. +  * 1. Redistributions of source code must retain the above copyright
  1190. +  *    notice, this list of conditions and the following disclaimer.
  1191. +  * 2. Redistributions in binary form must reproduce the above copyright
  1192. +  *    notice, this list of conditions and the following disclaimer in the
  1193. +  *    documentation and/or other materials provided with the distribution.
  1194. +  * 3. All advertising materials mentioning features or use of this software
  1195. +  *    must display the following acknowledgement:
  1196. +  *  This product includes software developed by Manuel Bouyer.
  1197. +  * 4. The name of the author may not be used to endorse or promote products
  1198. +  *    derived from this software without specific prior written permission.
  1199. +  *
  1200. +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  1201. +  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1202. +  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  1203. +  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  1204. +  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  1205. +  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  1206. +  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  1207. +  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1208. +  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1209. +  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1210. +  */
  1211. + /* Definition of atapi commands and associated data structures */
  1212. + /* 
  1213. +    TEST UNIT READY (mandatory)
  1214. +  */
  1215. + #define ATAPI_TEST_UNIT_READY           0x00
  1216. + struct test_unit_ready {
  1217. +     u_char  operation_code;
  1218. +     u_char  reserved1[15];
  1219. + };
  1220. + /* 
  1221. +    START/STOP UNIT (mandatory)
  1222. +    */ 
  1223. +  
  1224. + #define ATAPI_START_STOP_UNIT           0x1b
  1225. +  
  1226. + struct start_stop_unit {
  1227. +     u_char  operation_code;
  1228. +     u_char  immed       :1;
  1229. +     u_char  reserved1   :7;
  1230. +     u_char  reserved2[2]; 
  1231. +     u_char  how;
  1232. + #define SSS_STOP        0x00 
  1233. + #define SSS_START       0x01
  1234. + #define SSS_LOEJ        0x02
  1235. +     u_char  reserved4[11];
  1236. + };
  1237. + /* 
  1238. +    PREVENT/ALLOW MEDIUM REMOVAL (mandatory)
  1239. +    */ 
  1240. +  
  1241. + #define ATAPI_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
  1242. +  
  1243. + struct prevent_allow_medium_removal {
  1244. +     u_char  operation_code;
  1245. +     u_char  reserved1[3];
  1246. +     u_char  prevent     :1;
  1247. + #define PR_PREVENT 0x01
  1248. + #define PR_ALLOW   0x00
  1249. +     u_char  reserved2   :7;
  1250. +     u_char  reserved3[11];
  1251. + };
  1252. + /* 
  1253. +    READ CD CAPACITY (mandatory)
  1254. +  */
  1255. +        
  1256. + #define ATAPI_READ_CD_CAPACITY          0x25
  1257. +     
  1258. + struct read_cd_capacity {
  1259. +     u_char  operation_code;
  1260. +     u_char  reserved1[7];
  1261. +     u_char len;
  1262. +     u_char reserved2[7];
  1263. + };
  1264. + /* 
  1265. +  * Volume size info.
  1266. +  */
  1267. + struct read_cd_capacity_data {
  1268. +     u_long size;         /* Volume size in blocks */
  1269. +     u_long blksize;         /* Block size in bytes */
  1270. + };
  1271. + /*
  1272. +    READ (10) (mandatory)
  1273. +  */  
  1274. +     
  1275. + #define ATAPI_READ              0x28  
  1276. + struct read {    
  1277. +     u_char  operation_code;
  1278. +     u_char  reserved1;  
  1279. +     u_char  lba[4];       
  1280. +     u_char  reserved2;            
  1281. +     u_char  length[2];                    
  1282. +     u_char  reserved3[7];                         
  1283. + }; 
  1284. + /* 
  1285. +    PAUSE/RESUME (optional) 
  1286. +  */ 
  1287. +  
  1288. + #define ATAPI_PAUSE_RESUME      0x4b
  1289. +  
  1290. + struct pause_resume {
  1291. +     u_char  operation_code;
  1292. +     u_char  reserved1[7];
  1293. +     u_char  resume      :1;
  1294. +     u_char  reserved2   :7;
  1295. +     u_char  reserved3[7];
  1296. + };
  1297. + /*
  1298. +    MODE SENSE (mandatory)
  1299. +    */
  1300. + #define ATAPI_MODE_SENSE        0x5a
  1301. + struct mode_sense {
  1302. +     u_char  operation_code;
  1303. +     u_char  reserved1;
  1304. +     u_char  page_code   :6;
  1305. +     u_char  page_control    :2;  /* page control */
  1306. +     u_char  reserved2[4];
  1307. +     u_char  length[2];
  1308. +     u_char  reserved3[7];
  1309. + };
  1310. + struct cappage {
  1311. +     /* Mode data header */
  1312. +     u_short data_length;
  1313. +     u_char  medium_type;
  1314. + #define MDT_UNKNOWN     0x00        
  1315. + #define MDT_DATA_120    0x01
  1316. + #define MDT_AUDIO_120   0x02
  1317. + #define MDT_COMB_120    0x03    
  1318. + #define MDT_PHOTO_120   0x04    
  1319. + #define MDT_DATA_80     0x05
  1320. + #define MDT_AUDIO_80    0x06
  1321. + #define MDT_COMB_80     0x07 
  1322. + #define MDT_PHOTO_80    0x08
  1323. + #define MDT_NO_DISC     0x70
  1324. + #define MDT_DOOR_OPEN   0x71
  1325. + #define MDT_FMT_ERROR   0x72
  1326. +     u_char  reserved1[5];
  1327. +     /* Capabilities page */
  1328. +     u_char  page_code;
  1329. + #define CAP_PAGE        0x2a
  1330. +     u_char  param_len;
  1331. +     u_char  reserved2[2];
  1332. +     u_char  audio_play : 1;         /* audio play supported */
  1333. +     u_char  composite : 1;          /* composite audio/video supported */
  1334. +     u_char  dport1 : 1;             /* digital audio on port 1 */
  1335. +     u_char  dport2 : 1;             /* digital audio on port 2 */
  1336. +     u_char  mode2_form1 : 1;        /* mode 2 form 1 (XA) read */
  1337. +     u_char  mode2_form2 : 1;        /* mode 2 form 2 format */
  1338. +     u_char  multisession : 1;       /* multi-session photo-CD */
  1339. +     u_char  : 1;
  1340. +     u_char  cd_da : 1;              /* audio-CD read supported */
  1341. +     u_char  cd_da_stream : 1;       /* CD-DA streaming */
  1342. +     u_char  rw : 1;                 /* combined R-W subchannels */
  1343. +     u_char  rw_corr : 1;            /* R-W subchannel data corrected */
  1344. +     u_char  c2 : 1;                 /* C2 error pointers supported */
  1345. +     u_char  isrc : 1;               /* can return the ISRC info */
  1346. +     u_char  upc : 1;                /* can return the catalog number UPC */
  1347. +     u_char  : 1;
  1348. +     u_char  lock : 1;               /* could be locked */
  1349. +     u_char  locked : 1;             /* current lock state */
  1350. +     u_char  prevent : 1;            /* prevent jumper installed */
  1351. +     u_char  eject : 1;              /* can eject */
  1352. +     u_char  : 1;
  1353. +     u_char  mech : 3;               /* loading mechanism type */
  1354. + #define MECH_CADDY      0
  1355. + #define MECH_TRAY       1
  1356. + #define MECH_POPUP      2
  1357. + #define MECH_CHANGER    4
  1358. + #define MECH_CARTRIDGE  5
  1359. +     u_char  sep_vol : 1;            /* independent volume of channels */
  1360. +     u_char  sep_mute : 1;           /* independent mute of channels */
  1361. +     u_char  : 6;
  1362. +     u_short max_speed;              /* max raw data rate in bytes/1000 */
  1363. +     u_short max_vol_levels;         /* number of discrete volume levels */
  1364. +     u_short buf_size;               /* internal buffer size in bytes/1024 */
  1365. +     u_short cur_speed;              /* current data rate in bytes/1000  */
  1366. +     /* Digital drive output format description (optional?) */
  1367. +     u_char  reserved3;
  1368. +     u_char  bckf : 1;               /* data valid on failing edge of BCK */
  1369. +     u_char  rch : 1;                /* high LRCK indicates left channel */
  1370. +     u_char  lsbf : 1;               /* set if LSB first */
  1371. +     u_char  dlen: 2;
  1372. + #define DLEN_32         0               /* 32 BCKs */
  1373. + #define DLEN_16         1               /* 16 BCKs */
  1374. + #define DLEN_24         2               /* 24 BCKs */
  1375. + #define DLEN_24_I2S     3               /* 24 BCKs (I2S) */
  1376. +     u_char  : 3;
  1377. +     u_char  reserved4[2];
  1378. + };
  1379. + /* ATAPI error codes */
  1380. + #define ATAPI_SK_NO_SENSE       0x0
  1381. + #define ATAPI_SK_REC_ERROR      0x1  /* recovered error */
  1382. + #define ATAPI_SK_NOT_READY      0x2
  1383. + #define ATAPI_SK_MEDIUM_ERROR       0x3
  1384. + #define ATAPI_SK_HARDWARE_ERROR     0x4
  1385. + #define ATAPI_SK_ILLEGAL_REQUEST    0x5
  1386. + #define ATAPI_SK_UNIT_ATTENTION     0x6
  1387. + #define ATAPI_SK_DATA_PROTECT       0x7
  1388. +                          /* 0x8 reserved */
  1389. +                          /* 0x9-0xa reserved */
  1390. + #define ATAPI_SK_ABORTED_COMMAND    0xb
  1391. +                         /* 0xc-0xd not referenced */
  1392. + #define ATAPI_SK_MISCOMPARE     0xe
  1393. +                         /* 0xf reserved */
  1394. + #define ATAPI_MCR           0x08 /* media change requested */
  1395. + #define ATAPI_ABRT          0x04 /* aborted command */
  1396. + #define ATAPI_EOM           0x02 /* end of media */
  1397. + #define ATAPI_ILI           0x01 /* illegal length indication */
  1398. + int atapi_exec_cmd __P((struct at_dev_link *, void*, int, void*, int, long, int));
  1399. + int atapi_exec_io __P((struct at_dev_link *, void *, int, struct buf *, int));
  1400. + int atapi_test_unit_ready __P((struct at_dev_link  *, int));
  1401. + int atapi_start_stop __P((struct at_dev_link  *, int, int));
  1402. + int atapi_prevent __P((struct at_dev_link  *, int));
  1403. diff -c -r -N --exclude exp --exclude compile sys/atapi.orig/atapiconf.c sys/atapi/atapiconf.c
  1404. *** sys/atapi.orig/atapiconf.c    Thu Jan  1 01:00:00 1970
  1405. --- sys/atapi/atapiconf.c    Thu Jun 13 03:19:49 1996
  1406. ***************
  1407. *** 0 ****
  1408. --- 1,588 ----
  1409. + /*
  1410. +  * Copyright (c) 1996 Manuel Bouyer.  All rights reserved.
  1411. +  *
  1412. +  * Redistribution and use in source and binary forms, with or without
  1413. +  * modification, are permitted provided that the following conditions
  1414. +  * are met:
  1415. +  * 1. Redistributions of source code must retain the above copyright
  1416. +  *    notice, this list of conditions and the following disclaimer.
  1417. +  * 2. Redistributions in binary form must reproduce the above copyright
  1418. +  *    notice, this list of conditions and the following disclaimer in the
  1419. +  *    documentation and/or other materials provided with the distribution.
  1420. +  * 3. All advertising materials mentioning features or use of this software
  1421. +  *    must display the following acknowledgement:
  1422. +  *  This product includes software developed by Manuel Bouyer.
  1423. +  * 4. The name of the author may not be used to endorse or promote products
  1424. +  *    derived from this software without specific prior written permission.
  1425. +  *
  1426. +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  1427. +  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1428. +  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  1429. +  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  1430. +  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  1431. +  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  1432. +  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  1433. +  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1434. +  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1435. +  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1436. +  */
  1437. + #include <sys/types.h>
  1438. + #include <sys/param.h>
  1439. + #include <sys/systm.h>
  1440. + #include <sys/malloc.h>
  1441. + #include <sys/device.h>
  1442. + #include <sys/buf.h>
  1443. + #include <sys/proc.h>  
  1444. + #include <atapi/atapilink.h>
  1445. + #include <atapi/atapi.h>
  1446. + #define SILENT_PRINTF(flags,string) if (!(flags & A_SILENT)) printf string
  1447. + struct atapibus_softc {
  1448. +     struct device sc_dev;
  1449. +     struct bus_link *b_link;
  1450. +     struct atapi_devices *ad_link[2];
  1451. + };
  1452. + LIST_HEAD(pkt_free_list, atapi_command_packet) pkt_free_list;
  1453. + void bswap __P((char*, int));
  1454. + void btrim __P((char*, int));
  1455. + int atapi_error __P((struct atapi_command_packet*));
  1456. + void atapi_sense __P((struct atapi_command_packet*, u_char, u_char));
  1457. + void at_print_addr __P((struct at_dev_link*, u_char));
  1458. + int atapibusmatch __P((struct device *, void *, void *));
  1459. + void atapibusattach __P((struct device *, struct device *, void *));
  1460. + struct cfattach atapibus_ca = {
  1461. +     sizeof(struct atapibus_softc), atapibusmatch, atapibusattach,
  1462. + };
  1463. + struct cfdriver atapibus_cd = {
  1464. +     NULL, "atapibus", DV_DULL
  1465. + };
  1466. + int
  1467. + atapibusmatch(parent, match, aux)
  1468. +         struct device *parent;
  1469. +         void *match, *aux;
  1470. + {
  1471. + /*    struct cfdata *cf = match;*/
  1472. +     struct bus_link *ab_link = aux;
  1473. +     if (ab_link == NULL ) return 0;
  1474. +     if (ab_link-> type != BUS) return 0;
  1475. +     return 1;
  1476. + }
  1477. + int
  1478. + atapiprint(aux, bus)
  1479. +     void *aux;
  1480. +     char *bus;
  1481. + {
  1482. +     struct at_dev_link *ad_link = aux;
  1483. +  
  1484. +      if (!bus)
  1485. +          printf(" drive %d: ", ad_link->drive); 
  1486. +      return QUIET; 
  1487. + }
  1488. + void atapibusattach(parent, self, aux)
  1489. +         struct device *parent, *self;
  1490. +         void *aux;
  1491. + {
  1492. +     struct atapibus_softc *ab = (struct atapibus_softc *)self;
  1493. +     struct bus_link *ab_link_proto = aux;
  1494. +     int drive;
  1495. +     struct atapi_identify ids;
  1496. +     struct atapi_identify *id = &ids;
  1497. +     struct at_dev_link *ad_link;
  1498. +     ab_link_proto->atapibus_softc = (caddr_t)ab;
  1499. +     ab->b_link = ab_link_proto;
  1500. +     printf("\n");
  1501. +     for (drive = 0; drive < 2 ; drive++) {
  1502. +         if (wdc_atapi_get_params(ab_link_proto, drive, id)) {
  1503. +             /*
  1504. +              * Shuffle string byte order.
  1505. +              * Mitsumi and NEC drives don't need this.
  1506. +              */
  1507. +             if (! ((id->model[0] == 'N' && id->model[1] == 'E') ||
  1508. +                 (id->model[0] == 'F' && id->model[1] == 'X')))
  1509. +                 bswap(id->model, sizeof(id->model));
  1510. +             bswap (id->serial_number, sizeof(id->serial_number));
  1511. +             bswap (id->firmware_revision, sizeof(id->firmware_revision));
  1512. +             /* Clean up the model name, serial and revision numbers. */
  1513. +             btrim (id->model, sizeof(id->model));
  1514. +             btrim (id->serial_number, sizeof(id->serial_number));
  1515. +             btrim (id->firmware_revision, sizeof(id->firmware_revision));
  1516. +             printf("atapibus%d drive%d: <%s, %s, %s> ",
  1517. +                 ab->sc_dev.dv_unit, drive, id->model, id->serial_number, id->firmware_revision);
  1518. +             switch (id->config.device_type) {
  1519. +             case ATAPI_DEVICE_TYPE_DAD: printf("direct, ");
  1520. +                                        break;
  1521. +             case ATAPI_DEVICE_TYPE_CD: printf("cdrom, ");
  1522. +                                        break;
  1523. +             case ATAPI_DEVICE_TYPE_OMD: printf(" optical, ");
  1524. +                                        break;
  1525. +             default: printf(" unknown type %d, ",id->config.device_type);
  1526. +             }
  1527. +             printf("%s.\n", id->config.removable?"removable":"fixed");
  1528. + #ifdef ATAPI_DEBUG_PROBE
  1529. +             printf("cmdsz %d drqtype %d\n",id->config.packet_size, id->config.drq_type);
  1530. + #endif
  1531. +             
  1532. +             ad_link = malloc(sizeof(*ad_link), M_DEVBUF, M_NOWAIT);
  1533. +             if (ad_link == NULL) {
  1534. +                 printf("Warning: cannot allocate memory for device\n");
  1535. +                 continue;
  1536. +             }
  1537. +             ad_link->drive = drive;
  1538. +             if (id->config.packet_size) ad_link->flags |= ACAP_LEN;
  1539. +             ad_link->flags |= id->config.drq_type << 8;
  1540. +             bcopy(id, &ad_link->id, sizeof(*id));
  1541. +             ad_link->bus=ab_link_proto;
  1542. +             if (config_found(self,ad_link,atapiprint) == NULL) {
  1543. +                 printf("atapibus:config not found\n");
  1544. +                 free(ad_link,M_DEVBUF);
  1545. +             }
  1546. +         }
  1547. +     }
  1548. + }
  1549. + void
  1550. + bswap (buf, len)
  1551. + char *buf;
  1552. + int len;
  1553. + {       
  1554. +     u_short *p = (u_short*) (buf + len);
  1555. +     while (--p >= (u_short*) buf)
  1556. +             *p = ntohs (*p);
  1557. + }   
  1558. + void
  1559. + btrim (buf, len)
  1560. + char *buf;
  1561. + int len;
  1562. + {
  1563. +     char *p; 
  1564. +      
  1565. +      /* Remove the trailing spaces. */
  1566. +      for (p=buf; p<buf+len; ++p)
  1567. +          if (! *p)
  1568. +              *p = ' ';
  1569. +          for (p=buf+len-1; p>=buf && *p==' '; --p)
  1570. +              *p = 0;
  1571. + }
  1572. + int atapi_exec_cmd(ad_link, cmd, cmd_size, databuf, datalen, rw, flags)
  1573. + struct at_dev_link *ad_link;
  1574. + void *cmd;
  1575. + int cmd_size;
  1576. + void *databuf;
  1577. + int datalen;
  1578. + long rw;
  1579. + int flags;
  1580. + {
  1581. +     struct atapi_command_packet *pkt;
  1582. +     struct bus_link *b_link = ad_link->bus;
  1583. +     int status, s;
  1584. +     pkt = atapi_get_pkt(ad_link, flags);
  1585. +     if (!pkt) return -1;
  1586. +     bcopy(cmd, &pkt->cmd_store, cmd_size);
  1587. +     pkt->command = &pkt->cmd_store;
  1588. +     pkt->command_size = (ad_link->flags & ACAP_LEN)?16:12;
  1589. +     pkt->databuf = databuf;
  1590. +     pkt->data_size = datalen;
  1591. +     pkt->flags = rw|(flags & 0xff)| (ad_link->flags & 0x0300);
  1592. +     pkt->drive = ad_link->drive;
  1593. +     wdc_atapi_send_command_packet(b_link, pkt);
  1594. +     if ((flags & (A_POLLED|A_NOSLEEP)) == 0 ) {
  1595. + #ifdef ATAPI_DEBUG_CMD
  1596. +         printf("atapi_exec_cmd: sleeping\n");
  1597. + #endif
  1598. +         s=splbio();
  1599. +         while ((pkt->status & ITSDONE) == 0)
  1600. +             tsleep(pkt,PRIBIO+1,"atapicmd",0);
  1601. +         splx(s);
  1602. + #ifdef ATAPI_DEBUG_CMD
  1603. +         printf("atapi_exec_cmd: done sleeping\n");
  1604. + #endif
  1605. +         status = pkt->status & STATUS_MASK;
  1606. +         atapi_free_pkt(pkt);
  1607. +     } else {
  1608. +         if ((flags & A_POLLED) != 0) {
  1609. +             if ((pkt->status & ERROR) && (pkt->error)) {
  1610. +                 atapi_error(pkt);
  1611. +                 SILENT_PRINTF(flags,("\n"));
  1612. +             }
  1613. +         }
  1614. +         status = pkt->status & STATUS_MASK;
  1615. +         if ((flags & A_POLLED) != 0)
  1616. +             atapi_free_pkt(pkt);
  1617. +     }
  1618. +     return status;
  1619. + }
  1620. + int atapi_exec_io(ad_link, cmd, cmd_size, bp, flags)
  1621. + struct at_dev_link *ad_link;
  1622. + void *cmd;
  1623. + int cmd_size;
  1624. + struct buf *bp;
  1625. + int flags;
  1626. + {
  1627. +     struct atapi_command_packet *pkt;
  1628. +     struct bus_link *b_link = ad_link->bus;
  1629. +     pkt = atapi_get_pkt(ad_link, flags);
  1630. +     if (pkt == NULL) {
  1631. +         printf("atapi_exec_io: no pkt\n");
  1632. +         return ERROR;
  1633. +     }
  1634. +     bcopy(cmd, &pkt->cmd_store, cmd_size);
  1635. +     pkt->command = &pkt->cmd_store;
  1636. +     pkt->command_size = (ad_link->flags & ACAP_LEN)?16:12;
  1637. +     pkt->bp = bp;
  1638. +     pkt->databuf = bp->b_data;
  1639. +     pkt->data_size = bp->b_bcount;
  1640. +     pkt->flags = bp->b_flags & ((B_READ|B_WRITE)|(flags & 0xff)|
  1641. +             (ad_link->flags & 0x0300));
  1642. +     pkt->drive = ad_link->drive;
  1643. +     wdc_atapi_send_command_packet(b_link, pkt);
  1644. +     return (pkt->status & STATUS_MASK);
  1645. + }
  1646. + void atapi_done(acp)
  1647. + struct atapi_command_packet *acp;
  1648. + {
  1649. +     struct at_dev_link *ad_link=acp->ad_link;
  1650. +     struct buf *bp = acp->bp;
  1651. +     int error = 0;
  1652. + #ifdef ATAPI_DEBUG_CMD
  1653. +     printf("atapi_done\n");
  1654. + #endif
  1655. +     if ((acp->status & ERROR) && (acp->error)) {
  1656. +         atapi_error(acp);
  1657. +         if (acp->status & RETRY) {
  1658. +             if (acp->retries <ATAPI_NRETRIES) {
  1659. +                 acp->retries++;
  1660. +                 acp->status = 0;
  1661. +                 acp->error = 0;
  1662. +                 SILENT_PRINTF(acp->flags & 0xff,(", retry #%d\n",acp->retries));
  1663. +                 wdc_atapi_send_command_packet(ad_link->bus, acp);
  1664. +                 return;
  1665. +             } else acp->status = ERROR;
  1666. +         }
  1667. +         SILENT_PRINTF(acp->flags & 0xff,("\n"));
  1668. +     }
  1669. +     acp->status |= ITSDONE;
  1670. +     if (ad_link->done) {
  1671. + #ifdef ATAPI_DEBUG_CMD
  1672. +         printf("calling private done\n");
  1673. + #endif
  1674. +         error = (*ad_link->done) (acp);
  1675. +         if (error == EJUSTRETURN) return;
  1676. +     }
  1677. +     if (acp->bp == NULL) {
  1678. + #ifdef ATAPI_DEBUG_CMD
  1679. +         printf("atapidone: wakeup acp\n");
  1680. + #endif
  1681. +         wakeup(acp);
  1682. +         return;
  1683. +     }
  1684. + #ifdef ATAPI_DEBUG_CMD
  1685. +     printf("atapi_done: status %d\n", acp->status);
  1686. + #endif
  1687. +     switch (acp->status&0x0f) {
  1688. +     case MEDIA_CHANGE:
  1689. +         if (ad_link->flags & ADEV_REMOVABLE) {
  1690. +             ad_link->flags &= ~ADEV_MEDIA_LOADED;
  1691. +         }
  1692. +         error=EIO;
  1693. +         break;
  1694. +     case NO_ERROR:
  1695. +         error=0;
  1696. +         break;
  1697. +     case ERROR:
  1698. +     case END_OF_MEDIA:
  1699. +     default:
  1700. +         error=EIO;
  1701. +         break;
  1702. +     }
  1703. +     switch (acp->status&0xf0) {
  1704. +     case NOT_READY:
  1705. +     case UNIT_ATTENTION:
  1706. +         if (ad_link->flags & ADEV_REMOVABLE) {  
  1707. +             ad_link->flags &= ~ADEV_MEDIA_LOADED;
  1708. +         }   
  1709. +         error=EIO;
  1710. +         break;
  1711. +     default:
  1712. +     }
  1713. +     if (error) {
  1714. +         bp->b_error = error;;
  1715. +         bp->b_flags |= B_ERROR;
  1716. +         bp->b_resid = bp->b_bcount;
  1717. +     } else {
  1718. +         bp->b_error = 0;
  1719. +         bp->b_resid = acp->data_size;
  1720. +     }
  1721. +     biodone(bp);
  1722. +     atapi_free_pkt(acp);
  1723. + }
  1724. + struct atapi_command_packet *
  1725. + atapi_get_pkt(ad_link, flags)
  1726. + struct at_dev_link *ad_link;
  1727. + int flags;
  1728. + {
  1729. +     struct atapi_command_packet *pkt;
  1730. +     int s;
  1731. +     s = splbio();
  1732. +     while (ad_link->openings <= 0) {
  1733. +         if (flags & A_NOSLEEP) {
  1734. +             splx(s);
  1735. +             return 0;
  1736. +         }
  1737. + #ifdef ATAPI_DEBUG_CMD
  1738. +         printf("atapi_get_pkt: sleeping\n");
  1739. + #endif
  1740. +         ad_link->flags |= ADEV_WAITING;
  1741. +         (void) tsleep(ad_link, PRIBIO, "getpkt", 0);
  1742. +     }
  1743. +     ad_link->openings--;
  1744. +     if ((pkt = pkt_free_list.lh_first) != 0) {
  1745. +         LIST_REMOVE(pkt, free_list);
  1746. +         splx(s);
  1747. +     } else {
  1748. +         splx(s);
  1749. +         pkt = malloc(sizeof(struct atapi_command_packet), M_DEVBUF,
  1750. +             ((flags & A_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK));
  1751. +         if (!pkt) {
  1752. +             printf("atapi_get_pkt: cannot allocate pkt\n");
  1753. +             ad_link->openings++;
  1754. +             return 0;
  1755. +         }
  1756. +     }
  1757. +     bzero(pkt, sizeof(struct atapi_command_packet));
  1758. +     pkt->ad_link = ad_link;
  1759. +     return pkt;
  1760. + }
  1761. + void
  1762. + atapi_free_pkt(pkt)
  1763. + struct atapi_command_packet *pkt;
  1764. + {
  1765. +     struct at_dev_link *ad_link = pkt->ad_link;
  1766. +     int s;
  1767. +     s = splbio();
  1768. +     LIST_INSERT_HEAD(&pkt_free_list, pkt, free_list);
  1769. +     ad_link->openings++;
  1770. +     if ((ad_link->flags & ADEV_WAITING) != 0) {
  1771. +         ad_link->flags &= ~ADEV_WAITING;
  1772. +         wakeup(ad_link);
  1773. +     } else {
  1774. +         if (ad_link->start) {
  1775. + #ifdef ATAPI_DEBUG_CMD
  1776. +             printf("atapi_free_pkt: calling private start\n");
  1777. + #endif
  1778. +             (*(ad_link->start)) ((void*)ad_link->device_softc);
  1779. +         }
  1780. +     }
  1781. +     splx(s);
  1782. + }
  1783. + int
  1784. + atapi_test_unit_ready(ad_link, flags)
  1785. + struct at_dev_link  *ad_link;
  1786. + int flags;
  1787. + {    
  1788. +     int ret;
  1789. +     struct test_unit_ready cmd;
  1790. + #ifdef ATAPI_DEBUG_FCTN
  1791. +     printf("atapi_test_unit_ready: ");
  1792. + #endif
  1793. +     bzero(&cmd, sizeof(cmd));
  1794. +     cmd.operation_code = ATAPI_TEST_UNIT_READY;
  1795. +     ret = atapi_exec_cmd(ad_link, &cmd, sizeof(cmd), 0,0,0,flags);
  1796. + #ifdef ATAPI_DEBUG_FCTN
  1797. +     printf("atapi_test_unit_ready: ret %d\n", ret);
  1798. + #endif
  1799. +     return ret;
  1800. + }
  1801. + int
  1802. + atapi_start_stop(ad_link, how, flags)
  1803. + struct at_dev_link  *ad_link;
  1804. + int how;
  1805. + int flags;
  1806. + {
  1807. +     struct start_stop_unit cmd;
  1808. +     int ret;
  1809. +         
  1810. + #ifdef ATAPI_DEBUG_FCTN
  1811. +     printf("atapi_start_stop: ");
  1812. + #endif
  1813. +     bzero(&cmd, sizeof(cmd));
  1814. +     cmd.operation_code = ATAPI_START_STOP_UNIT;
  1815. +     cmd.how = how;
  1816. +     ret = atapi_exec_cmd(ad_link, &cmd, sizeof(cmd), 0,0,0,flags);
  1817. + #ifdef ATAPI_DEBUG_FCTN
  1818. +     printf("ret %d\n", ret);
  1819. + #endif
  1820. +     return ret;
  1821. + }
  1822. + int
  1823. + atapi_prevent(ad_link, how)
  1824. + struct at_dev_link  *ad_link;
  1825. + int how;
  1826. + {
  1827. +     struct prevent_allow_medium_removal cmd;
  1828. +     int ret;
  1829. + #ifdef ATAPI_DEBUG_FCTN
  1830. +     printf("atapi_prevent: ");
  1831. + #endif
  1832. +     bzero(&cmd, sizeof(cmd));
  1833. +     cmd.operation_code = ATAPI_PREVENT_ALLOW_MEDIUM_REMOVAL;
  1834. +     cmd.prevent = how;
  1835. +     ret = atapi_exec_cmd(ad_link, &cmd, sizeof(cmd), 0,0,0,0);
  1836. + #ifdef ATAPI_DEBUG_FCTN
  1837. +     printf("ret %d\n", ret);
  1838. + #endif
  1839. +     return ret;
  1840. + }
  1841. + int 
  1842. + atapi_error(acp)
  1843. + struct atapi_command_packet* acp;
  1844. + {
  1845. +     int flags, error, ret = -1;
  1846. +     struct at_dev_link *ad_link = acp->ad_link;
  1847. +     flags = acp->flags & 0xff;
  1848. +     error = acp->error;
  1849. +     at_print_addr(ad_link, acp->flags & 0xff);
  1850. +     if (error & ATAPI_MCR) {
  1851. +         SILENT_PRINTF(flags,("media change requested"));
  1852. +         acp->status = MEDIA_CHANGE;
  1853. +     }
  1854. +     if (error & ATAPI_ABRT) {      
  1855. +         SILENT_PRINTF(flags,("command aborted"));
  1856. +         acp->status = ERROR; 
  1857. +     }
  1858. +     if (error & ATAPI_EOM) {
  1859. +         SILENT_PRINTF(flags,("end of media"));
  1860. +         acp->status = END_OF_MEDIA;
  1861. +     }
  1862. +     if (error & ATAPI_ILI) {
  1863. +         SILENT_PRINTF(flags,("illegal length indication"));
  1864. +         acp->status = ERROR;
  1865. +     }
  1866. +     if ((error & 0x0f) == 0) {
  1867. +         ret=0;
  1868. +     }
  1869. +     atapi_sense (acp, error >> 4, flags);
  1870. +     if (!(flags & A_SILENT) && (acp->status != NO_ERROR)) {
  1871. +         int i;
  1872. +         printf(", command:");
  1873. +         for (i=0; i< acp->command_size; i++)
  1874. +             printf(" %2x", ((u_char*)acp->command)[i]);
  1875. +     }
  1876. +     return ret;
  1877. + }
  1878. + void
  1879. + atapi_sense(acp, sense_key, flags)
  1880. + struct atapi_command_packet *acp;
  1881. + u_char sense_key;
  1882. + u_char flags;
  1883. + {
  1884. +     struct at_dev_link *ad_link = acp->ad_link;
  1885. +     switch (sense_key)
  1886. +     {
  1887. +     case ATAPI_SK_NO_SENSE:
  1888. +     break;
  1889. +     case ATAPI_SK_REC_ERROR:
  1890. +     SILENT_PRINTF(flags,("recovered error"));
  1891. +     acp->status = 0;
  1892. +     break;
  1893. +     case ATAPI_SK_NOT_READY:
  1894. +     SILENT_PRINTF(flags,("not ready"));
  1895. +     acp->status = NOT_READY;
  1896. +     break;
  1897. +     case ATAPI_SK_MEDIUM_ERROR:
  1898. +     SILENT_PRINTF(flags,("medium error"));
  1899. +     acp->status = ERROR;
  1900. +     break;
  1901. +     case ATAPI_SK_HARDWARE_ERROR:
  1902. +     SILENT_PRINTF(flags,("hardware error"));
  1903. +     acp->status = ERROR;
  1904. +     break;
  1905. +     case ATAPI_SK_ILLEGAL_REQUEST:
  1906. +     SILENT_PRINTF(flags,("illegal request"));
  1907. +     acp->status = ERROR;
  1908. +     break;
  1909. +     case ATAPI_SK_UNIT_ATTENTION:
  1910. +     SILENT_PRINTF(flags,("unit attention"));
  1911. +     acp->status = UNIT_ATTENTION;
  1912. +     if (ad_link->flags & ADEV_REMOVABLE) {  
  1913. +         ad_link->flags &= ~ADEV_MEDIA_LOADED;
  1914. +     }   
  1915. +     break;
  1916. +     case ATAPI_SK_DATA_PROTECT:
  1917. +     SILENT_PRINTF(flags,("data protect"));
  1918. +     acp->status = ERROR;
  1919. +     break;
  1920. +     case ATAPI_SK_ABORTED_COMMAND:
  1921. +     SILENT_PRINTF(flags,("aborted command"));
  1922. +     acp->status = RETRY;
  1923. +     break;
  1924. +     case ATAPI_SK_MISCOMPARE:
  1925. +     SILENT_PRINTF(flags,("miscompare"));
  1926. +     acp->status = ERROR;
  1927. +     break;
  1928. +     default:
  1929. +     SILENT_PRINTF(flags,("unexpected sense key %02x", sense_key));
  1930. +     acp->status = ERROR;
  1931. +     break;
  1932. +     }
  1933. + }
  1934. + void
  1935. + at_print_addr(ad_link, flags)
  1936. +     struct at_dev_link *ad_link; 
  1937. +     u_char flags;
  1938. + {
  1939. +     if (flags & A_SILENT) return;
  1940. +     printf("%s(%s:%d): ",
  1941. +         ad_link->device_softc ?
  1942. +         ((struct device *)ad_link->device_softc)->dv_xname : "probe",
  1943. +         ((struct device *)ad_link->bus->wdc_softc)->dv_xname,
  1944. +         ad_link->drive);
  1945. + }       
  1946. diff -c -r -N --exclude exp --exclude compile sys/atapi.orig/atapilink.h sys/atapi/atapilink.h
  1947. *** sys/atapi.orig/atapilink.h    Thu Jan  1 01:00:00 1970
  1948. --- sys/atapi/atapilink.h    Thu Jun 13 03:19:49 1996
  1949. ***************
  1950. *** 0 ****
  1951. --- 1,186 ----
  1952. + /*
  1953. +  * Copyright (c) 1996 Manuel Bouyer.  All rights reserved.
  1954. +  *
  1955. +  * Redistribution and use in source and binary forms, with or without
  1956. +  * modification, are permitted provided that the following conditions
  1957. +  * are met:
  1958. +  * 1. Redistributions of source code must retain the above copyright
  1959. +  *    notice, this list of conditions and the following disclaimer.
  1960. +  * 2. Redistributions in binary form must reproduce the above copyright
  1961. +  *    notice, this list of conditions and the following disclaimer in the
  1962. +  *    documentation and/or other materials provided with the distribution.
  1963. +  * 3. All advertising materials mentioning features or use of this software
  1964. +  *    must display the following acknowledgement:
  1965. +  *  This product includes software developed by Manuel Bouyer.
  1966. +  * 4. The name of the author may not be used to endorse or promote products
  1967. +  *    derived from this software without specific prior written permission.
  1968. +  *
  1969. +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  1970. +  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1971. +  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  1972. +  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  1973. +  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  1974. +  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  1975. +  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  1976. +  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1977. +  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1978. +  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1979. +  */
  1980. + #undef ATAPI_DEBUG
  1981. + #undef ATAPI_DEBUG_PROBE
  1982. + struct bus_link {
  1983. +     u_int8_t type;  
  1984. + #define DRIVE 0
  1985. + #define BUS 1
  1986. +     caddr_t wdc_softc;
  1987. +     caddr_t atapibus_softc;
  1988. +     struct wdc_link *ctlr_link;
  1989. +     u_int8_t ctrl;
  1990. + };
  1991. + struct atapi_identify {
  1992. +     struct config_s {
  1993. +     u_int8_t  packet_size :2;
  1994. + #define ATAPI_PACKET_SIZE_12        0x0
  1995. + #define ATAPI_PACKET_SIZE_16        0x1
  1996. +                          /* 1xb reserved */
  1997. +     u_int8_t  reserved1   :3;
  1998. +     u_int8_t  drq_type    :2;
  1999. + #define ATAPI_MICROPROCESSOR_DRQ    0x0
  2000. + #define ATAPI_INTERRUPT_DRQ     0x1
  2001. + #define ATAPI_ACCELERATED_DRQ       0x2
  2002. +                          /* 0x3 reserved */
  2003. +     u_int8_t  removable   :1;
  2004. +     u_int8_t  device_type :5;
  2005. + #define ATAPI_DEVICE_TYPE_DAD       0x0  /* direct access device, eg magnetic di
  2006. + sk */
  2007. +                          /* 0x1-0x4 reserved */
  2008. + #define ATAPI_DEVICE_TYPE_CD        0x5
  2009. +                          /* 0x6 reserved */
  2010. + #define ATAPI_DEVICE_TYPE_OMD       0x7  /* optical memory device */
  2011. +                          /* 0x8-0x1e reserved */
  2012. + #define ATAPI_DEVICE_TYPE_UNKNOWN   0x1f
  2013. +     u_int8_t  reserved2   :1;
  2014. +     u_int8_t  protocol_type   :2;
  2015. +                          /* 0x0, 0x1 are ATA */
  2016. + #define ATAPI_GC_PROTO_TYPE_ATAPI   0x2
  2017. + #define ATAPI_GC_PROTO_TYPE_RESERVED    0x3
  2018. +     } config;                /* general configuration */
  2019. +     u_int16_t cylinders;
  2020. +     u_int16_t reserved1;
  2021. +     u_int16_t heads;
  2022. +     u_int16_t unf_bytes_per_track;
  2023. +     u_int16_t unf_bytes_per_sector;
  2024. +     u_int16_t sectors_per_track;
  2025. +     u_int16_t reserved2[3];
  2026. +     char    serial_number[20];
  2027. +     u_int16_t buffer_type;
  2028. +     u_int16_t buffer_size;
  2029. +     u_int16_t ECC_bytes_available;
  2030. +     char    firmware_revision[8];
  2031. +     char    model[40];
  2032. +     u_int16_t sector_count;
  2033. +     u_int16_t double_word;             /* ==0 for CD-ROMs */
  2034. +     struct capabilities_s {
  2035. +       u_int8_t    vendor;
  2036. +       u_int8_t    dma     :1;      /* DMA supported */
  2037. +       u_int8_t    lba     :1;      /* LBA supported */
  2038. +       u_int8_t    iordy_disable   :1;      /* IORDY can be disabled */
  2039. +       u_int8_t    iordy       :1;      /* IORDY supported */
  2040. +       u_int8_t    reserved1   :4;
  2041. +     } capabilities;
  2042. +     u_int16_t reserved3;
  2043. +     u_int16_t PIO_cycle_timing;
  2044. +     u_int16_t DMA_cycle_timing;
  2045. +     u_int16_t validity;            /* of words 54-58, 64-70 in this table */
  2046. + #define ATAPI_VALID_FIRST       0x0  /* == 1 => words 54-58 are valid */
  2047. + #define ATAPI_VALID_SECOND      0x1  /* == 1 => words 64-70 are valid */
  2048. +     u_int16_t current_chs[3];          /* cylinder/head/sector */
  2049. +     u_int16_t current_capacity[2];
  2050. +     u_int16_t reserved4;
  2051. +     u_int16_t user_addressable_sectors[2];
  2052. +     u_int16_t singleword_DMA_mode;
  2053. + #define ATAPI_SW_DMA_MODE_AVAIL     0x00ff /* bit 0 set => Mode 0 is supported */
  2054. + #define ATAPI_SW_DMA_MODE_ACTIVE    0xff00 /* which mode is active */
  2055. +     u_int16_t multiword_DMA_mode;
  2056. + #define ATAPI_MW_DMA_MODE_AVAIL     0x00ff /* bit 0 set => Mode 0 is supported */
  2057. + #define ATAPI_MW_DMA_MODE_ACTIVE    0xff00 /* which mode is active */
  2058. +     u_int16_t enhanced_PIO_mode;
  2059. + #define ATAPI_ENHANCED_PIO_AVAIL    0x0001 /* bit 0 set => PIO Mode 3 is support
  2060. + ed */
  2061. +     u_int16_t blind_PIO_minimum_cycles;
  2062. +     u_int16_t mw_dma_tct;          /* multi-word DMA transfer cycle time */
  2063. +     u_int16_t min_PIO_tct_no_flow_control;
  2064. +     u_int16_t min_PIO_tct_with_flow_control;
  2065. +     u_int16_t reserved5[2];
  2066. +     u_int16_t reserved6[57];
  2067. +     u_int16_t vendor[32];          /* vendor unique */
  2068. +     u_int16_t reserved7[96];
  2069. + };
  2070. + struct at_dev_link {
  2071. +     void *device_softc;
  2072. +     u_int8_t drive;
  2073. +     u_int8_t openings;
  2074. +     struct atapi_identify id;  
  2075. +     struct bus_link *bus;
  2076. +     u_int16_t flags;
  2077. + #define ADEV_REMOVABLE      0x001    /* media is removable */
  2078. + #define ADEV_MEDIA_LOADED   0x002    /* device figures are still valid */  
  2079. + #define ADEV_WAITING        0x004    /* a process is waiting for this */
  2080. + #define ADEV_OPEN           0x008    /* at least 1 open session */
  2081. + #define ACAP_DRQ_MPROC        0x000   /* microprocessor DRQ */
  2082. + #define ACAP_DRQ_INTR        0x100    /* interrupt DRQ */
  2083. + #define ACAP_DRQ_ACCEL        0x200    /* accelerated DRQ */
  2084. + #define ACAP_LEN             0x400   /* 16 bit commands */
  2085. +     void (*start)();
  2086. +     int (*done)();
  2087. + };
  2088. + struct atapi_command_packet {
  2089. +     void *ad_link;
  2090. +     void *command;
  2091. +     char cmd_store[16];
  2092. +     int command_size;
  2093. +     struct buf* bp; 
  2094. +     void *databuf;
  2095. +     int data_size;
  2096. +     long flags;   /* handle B_READ/B_WRITE mask 0x00f00000 */
  2097. +                   /* controller flags maks 0x0000000f */
  2098. +                   /* ATAPI flags mask 0x000000f0 */
  2099. +                   /* Capabilities flags 0x00000f00 */
  2100. +     u_int8_t drive;
  2101. +     u_int16_t status;
  2102. + #define STATUS_MASK 0xff
  2103. + #define NO_ERROR 0x00
  2104. + #define ERROR 0x01
  2105. + #define MEDIA_CHANGE 0x02
  2106. + #define END_OF_MEDIA 0x03
  2107. + #define NOT_READY 0x10
  2108. + #define UNIT_ATTENTION 0x20
  2109. + #define RETRY 0x40
  2110. + #define ITSDONE 0x100
  2111. +     u_int8_t error;
  2112. +     u_int8_t retries;
  2113. + #define ATAPI_NRETRIES 5
  2114. +     LIST_ENTRY(atapi_command_packet) free_list;
  2115. + };
  2116. + int wdc_atapi_get_params  __P((struct bus_link *,u_int8_t, struct atapi_identify *)); 
  2117. + void wdc_atapi_send_command_packet __P((struct bus_link*, struct atapi_command_packet*));
  2118. + #define A_POLLED 0x10
  2119. + #define A_NOSLEEP 0x20
  2120. + #define A_SILENT 0x40
  2121. + void atapi_done __P((struct atapi_command_packet *));
  2122. + struct atapi_command_packet *atapi_get_pkt __P((struct at_dev_link *, int));
  2123. + void atapi_free_pkt __P((struct atapi_command_packet *));
  2124. diff -c -r -N --exclude exp --exclude compile sys/atapi.orig/files.atapi sys/atapi/files.atapi
  2125. *** sys/atapi.orig/files.atapi    Thu Jan  1 01:00:00 1970
  2126. --- sys/atapi/files.atapi    Thu Jun 13 03:19:50 1996
  2127. ***************
  2128. *** 0 ****
  2129. --- 1,14 ----
  2130. + #
  2131. + # Config.new file and device description for machine-independent ATAPI code.
  2132. + # Included by ports that need it.  Ports that usee it must provide
  2133. + # their own "major" declarations for the appropriate devices.
  2134. + define    atapi {}
  2135. + file    atapi/atapiconf.c            atapi
  2136. + device    atapibus {drive = -1}
  2137. + attach    atapibus at atapi
  2138. + device  acd: disk
  2139. + attach  acd at atapibus
  2140. + file    atapi/acd.c           acd needs-flag
  2141.