sd.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /* $OpenBSD: sd.c,v 1.5 2014/07/12 21:03:38 tedu Exp $ */
  2. /* $NetBSD: sd.c,v 1.5 2013/01/22 15:48:40 tsutsui Exp $ */
  3. /*
  4. * Copyright (c) 1992 OMRON Corporation.
  5. *
  6. * This code is derived from software contributed to Berkeley by
  7. * OMRON Corporation.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed by the University of
  20. * California, Berkeley and its contributors.
  21. * 4. Neither the name of the University nor the names of its contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35. * SUCH DAMAGE.
  36. *
  37. * @(#)sd.c 8.1 (Berkeley) 6/10/93
  38. */
  39. /*
  40. * Copyright (c) 1992, 1993
  41. * The Regents of the University of California. All rights reserved.
  42. *
  43. * This code is derived from software contributed to Berkeley by
  44. * OMRON Corporation.
  45. *
  46. * Redistribution and use in source and binary forms, with or without
  47. * modification, are permitted provided that the following conditions
  48. * are met:
  49. * 1. Redistributions of source code must retain the above copyright
  50. * notice, this list of conditions and the following disclaimer.
  51. * 2. Redistributions in binary form must reproduce the above copyright
  52. * notice, this list of conditions and the following disclaimer in the
  53. * documentation and/or other materials provided with the distribution.
  54. * 3. Neither the name of the University nor the names of its contributors
  55. * may be used to endorse or promote products derived from this software
  56. * without specific prior written permission.
  57. *
  58. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  59. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  60. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  61. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  62. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  63. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  64. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  65. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  66. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  67. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  68. * SUCH DAMAGE.
  69. *
  70. * @(#)sd.c 8.1 (Berkeley) 6/10/93
  71. */
  72. /*
  73. * sd.c -- SCSI DISK device driver
  74. * by A.Fujita, FEB-26-1992
  75. */
  76. /*
  77. * SCSI CCS (Command Command Set) disk driver.
  78. */
  79. #include <sys/param.h>
  80. #include <sys/disklabel.h>
  81. #include <luna88k/stand/boot/samachdep.h>
  82. #include <luna88k/stand/boot/scsireg.h>
  83. #include <luna88k/stand/boot/scsivar.h>
  84. struct sd_softc {
  85. uint sc_ctlr;
  86. uint sc_tgt;
  87. uint sc_part;
  88. short sc_type; /* drive type */
  89. short sc_punit; /* physical unit (scsi lun) */
  90. u_short sc_bshift; /* convert device blocks to DEV_BSIZE blks */
  91. daddr32_t sc_blks; /* number of blocks on device */
  92. int sc_blksize; /* device block size in bytes */
  93. struct disklabel sc_label;
  94. struct scsi_softc sc_sc;
  95. };
  96. struct sd_softc *sdinit(uint, uint);
  97. static int sdident(struct sd_softc *);
  98. static struct scsi_inquiry inqbuf;
  99. static struct scsi_generic_cdb inq = {
  100. 6,
  101. { CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 }
  102. };
  103. static u_long capbuf[2];
  104. struct scsi_generic_cdb cap = {
  105. 10,
  106. { CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  107. };
  108. int
  109. sdident(struct sd_softc *sc)
  110. {
  111. #ifdef DEBUG
  112. char idstr[32];
  113. #endif
  114. uint ctlr, target, unit;
  115. int i;
  116. int tries = 10;
  117. ctlr = sc->sc_ctlr;
  118. target = sc->sc_tgt;
  119. unit = sc->sc_punit;
  120. if (scinit(&sc->sc_sc, ctlr) == 0)
  121. return -1;
  122. /*
  123. * See if unit exists and is a disk then read block size & nblocks.
  124. */
  125. while ((i = scsi_test_unit_rdy(&sc->sc_sc, target, unit)) != 0) {
  126. if (i < 0 || --tries < 0)
  127. return (-1);
  128. if (i == STS_CHECKCOND) {
  129. u_char sensebuf[8];
  130. struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf;
  131. scsi_request_sense(&sc->sc_sc, target, unit, sensebuf,
  132. sizeof sensebuf);
  133. if (sp->class == 7 && sp->key == 6)
  134. /* drive doing an RTZ -- give it a while */
  135. DELAY(1000000);
  136. }
  137. DELAY(1000);
  138. }
  139. if (scsi_immed_command(&sc->sc_sc, target, unit, &inq,
  140. (u_char *)&inqbuf, sizeof(inqbuf)) ||
  141. scsi_immed_command(&sc->sc_sc, target, unit, &cap,
  142. (u_char *)&capbuf, sizeof(capbuf)))
  143. /* doesn't exist or not a CCS device */
  144. return (-1);
  145. switch (inqbuf.type) {
  146. case 0: /* disk */
  147. case 4: /* WORM */
  148. case 5: /* CD-ROM */
  149. case 7: /* Magneto-optical */
  150. break;
  151. default: /* not a disk */
  152. return (-1);
  153. }
  154. sc->sc_blks = capbuf[0];
  155. sc->sc_blksize = capbuf[1];
  156. #ifdef DEBUG
  157. memcpy(idstr, &inqbuf.vendor_id, 28);
  158. for (i = 27; i > 23; --i)
  159. if (idstr[i] != ' ')
  160. break;
  161. idstr[i+1] = 0;
  162. for (i = 23; i > 7; --i)
  163. if (idstr[i] != ' ')
  164. break;
  165. idstr[i+1] = 0;
  166. for (i = 7; i >= 0; --i)
  167. if (idstr[i] != ' ')
  168. break;
  169. idstr[i+1] = 0;
  170. printf("sd(%d,%d): %s %s rev %s", ctlr, target, idstr, &idstr[8],
  171. &idstr[24]);
  172. printf(", %d bytes/sect x %d sectors\n", sc->sc_blksize, sc->sc_blks);
  173. #endif
  174. if (sc->sc_blksize != DEV_BSIZE) {
  175. if (sc->sc_blksize < DEV_BSIZE) {
  176. printf("sd(%d,%d): need %d byte blocks - drive ignored\n",
  177. ctlr, target, DEV_BSIZE);
  178. return (-1);
  179. }
  180. for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
  181. ++sc->sc_bshift;
  182. sc->sc_blks <<= sc->sc_bshift;
  183. }
  184. return(inqbuf.type);
  185. }
  186. struct sd_softc *
  187. sdinit(uint unit, uint part)
  188. {
  189. struct sd_softc *sc;
  190. struct disklabel *lp;
  191. char *msg;
  192. sc = alloc(sizeof *sc);
  193. if (sc == NULL)
  194. return NULL;
  195. memset(sc, 0, sizeof *sc);
  196. sc->sc_ctlr = unit / 10;
  197. sc->sc_tgt = unit % 10;
  198. sc->sc_part = part;
  199. #ifdef DEBUG
  200. printf("sdinit: ctlr = %d tgt = %d part = %d\n",
  201. sc->sc_ctlr, sc->sc_tgt, sc->sc_part);
  202. #endif
  203. sc->sc_punit = 0; /* XXX no LUN support yet */
  204. sc->sc_type = sdident(sc);
  205. if (sc->sc_type < 0)
  206. return(NULL);
  207. /*
  208. * Use the default sizes until we've read the label,
  209. * or longer if there isn't one there.
  210. */
  211. lp = &sc->sc_label;
  212. if (lp->d_secpercyl == 0) {
  213. lp->d_secsize = DEV_BSIZE;
  214. lp->d_nsectors = 32;
  215. lp->d_ntracks = 20;
  216. lp->d_secpercyl = 32*20;
  217. lp->d_npartitions = 1;
  218. lp->d_partitions[0].p_offset = 0;
  219. lp->d_partitions[0].p_size = LABELSECTOR + 1;
  220. }
  221. /*
  222. * read disklabel
  223. */
  224. msg = readdisklabel(&sc->sc_sc, sc->sc_tgt, lp);
  225. if (msg != NULL)
  226. printf("sd(%d,%d): %s\n", sc->sc_ctlr, sc->sc_tgt, msg);
  227. return sc;
  228. }
  229. int
  230. sdopen(struct open_file *f, ...)
  231. {
  232. va_list ap;
  233. struct sd_softc *sc;
  234. int unit, part;
  235. va_start(ap, f);
  236. unit = va_arg(ap, int);
  237. part = va_arg(ap, int);
  238. va_end(ap);
  239. if (part < 0 || part >= MAXPARTITIONS)
  240. return(-1);
  241. sc = sdinit(unit, part);
  242. if (sc == NULL)
  243. return -1;
  244. f->f_devdata = (void *)sc;
  245. return 0;
  246. }
  247. int
  248. sdclose(struct open_file *f)
  249. {
  250. struct sd_softc *sc = f->f_devdata;
  251. free(sc, sizeof *sc);
  252. f->f_devdata = NULL;
  253. return 0;
  254. }
  255. static struct scsi_generic_cdb cdb_read = {
  256. 10,
  257. { CMD_READ_EXT, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  258. };
  259. static struct scsi_generic_cdb cdb_write = {
  260. 6,
  261. { CMD_WRITE_EXT, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  262. };
  263. int
  264. sdstrategy(void *devdata, int func, daddr32_t dblk, size_t size, void *v_buf,
  265. size_t *rsize)
  266. {
  267. struct sd_softc *sc = devdata;
  268. struct disklabel *lp;
  269. uint8_t *buf = v_buf;
  270. int target = sc->sc_tgt;
  271. struct scsi_generic_cdb *cdb;
  272. daddr32_t blk;
  273. u_int nblk = size >> sc->sc_bshift;
  274. int stat;
  275. #ifdef DEBUG
  276. int i;
  277. #endif
  278. lp = &sc->sc_label;
  279. blk = dblk + (lp->d_partitions[sc->sc_part].p_offset >> sc->sc_bshift);
  280. if (func == F_READ)
  281. cdb = &cdb_read;
  282. else
  283. cdb = &cdb_write;
  284. cdb->cdb[2] = (blk & 0xff000000) >> 24;
  285. cdb->cdb[3] = (blk & 0x00ff0000) >> 16;
  286. cdb->cdb[4] = (blk & 0x0000ff00) >> 8;
  287. cdb->cdb[5] = (blk & 0x000000ff);
  288. cdb->cdb[7] = ((nblk >> _DEV_BSHIFT) & 0xff00) >> 8;
  289. cdb->cdb[8] = ((nblk >> _DEV_BSHIFT) & 0x00ff);
  290. #ifdef DEBUG
  291. printf("sdstrategy(%d,%d): blk = %lu (0x%lx), nblk = %u (0x%x)\n",
  292. sc->sc_ctlr, sc->sc_tgt, (u_long)blk, (long)blk, nblk, nblk);
  293. for (i = 0; i < 10; i++)
  294. printf("cdb[%d] = 0x%x\n", i, cdb->cdb[i]);
  295. #endif
  296. stat = scsi_immed_command(&sc->sc_sc, target, sc->sc_punit, cdb, buf,
  297. size);
  298. if (rsize)
  299. *rsize = size;
  300. return 0;
  301. }