scsi-bsd-os.c
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:8k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)scsi-bsd-os.c 1.11 99/09/07 Copyright 1997 J. Schilling */
  2. #ifndef lint
  3. static char __sccsid[] =
  4. "@(#)scsi-bsd-os.c 1.11 99/09/07 Copyright 1997 J. Schilling";
  5. #endif
  6. /*
  7.  * Interface for the BSD/OS user-land raw SCSI implementation.
  8.  *
  9.  * This is a hack, that tries to emulate the functionality
  10.  * of the scg driver.
  11.  *
  12.  * Copyright (c) 1997 J. Schilling
  13.  */
  14. /*
  15.  * This program is free software; you can redistribute it and/or modify
  16.  * it under the terms of the GNU General Public License as published by
  17.  * the Free Software Foundation; either version 2, or (at your option)
  18.  * any later version.
  19.  *
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU General Public License for more details.
  24.  *
  25.  * You should have received a copy of the GNU General Public License
  26.  * along with this program; see the file COPYING.  If not, write to
  27.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  28.  */
  29. #undef sense
  30. #define scsi_sense bsdi_scsi_sense
  31. #define scsi_inquiry bsdi_scsi_inquiry
  32. /*
  33.  * Must use -I/sys...
  34.  * The next two files are in /sys/dev/scsi
  35.  */
  36. #include <dev/scsi/scsi.h>
  37. #include <dev/scsi/scsi_ioctl.h>
  38. #define MAX_SCG 16 /* Max # of SCSI controllers */
  39. #define MAX_TGT 16
  40. #define MAX_LUN 8
  41. struct scg_local {
  42. short scgfiles[MAX_SCG][MAX_TGT][MAX_LUN];
  43. };
  44. #define scglocal(p) ((struct scg_local *)((p)->local)) 
  45. #include <machine/param.h>
  46. #define MAX_DMA_BSDI MAXPHYS /* More makes problems */
  47. LOCAL BOOL scsi_setup __PR((SCSI *scgp, int f, int busno, int tgt, int tlun));
  48. EXPORT int
  49. scsi_open(scgp, device, busno, tgt, tlun)
  50. SCSI *scgp;
  51. char *device;
  52. int busno;
  53. int tgt;
  54. int tlun;
  55. {
  56. register int f;
  57. register int b;
  58. register int t;
  59. register int l;
  60. register int nopen = 0;
  61. char devname[64];
  62. if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) {
  63. errno = EINVAL;
  64. if (scgp->errstr)
  65. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  66. "Illegal value for busno, target or lun '%d,%d,%d'",
  67. busno, tgt, tlun);
  68. return (-1);
  69. }
  70. if (scgp->local == NULL) {
  71. scgp->local = malloc(sizeof(struct scg_local));
  72. if (scgp->local == NULL)
  73. return (0);
  74. for (b=0; b < MAX_SCG; b++) {
  75. for (t=0; t < MAX_TGT; t++) {
  76. for (l=0; l < MAX_LUN ; l++)
  77. scglocal(scgp)->scgfiles[b][t][l] = (short)-1;
  78. }
  79. }
  80. }
  81. if ((device != NULL && *device != '') || (busno == -2 && tgt == -2)) {
  82. goto openbydev;
  83. if (busno >= 0 && tgt >= 0 && tlun >= 0) {
  84. sprintf(devname, "/dev/su%d-%d-%d", busno, tgt, tlun);
  85. f = open(devname, O_RDWR|O_NONBLOCK);
  86. if (f < 0) {
  87. goto openbydev;
  88. }
  89. scglocal(scgp)->scgfiles[busno][tgt][tlun] = f;
  90. return(1);
  91. } else for (b=0; b < MAX_SCG; b++) {
  92. for (t=0; t < MAX_TGT; t++) {
  93. for (l=0; l < MAX_LUN ; l++) {
  94. sprintf(devname, "/dev/su%d-%d-%d", b, t, l);
  95. f = open(devname, O_RDWR|O_NONBLOCK);
  96. /* error("open (%s) = %dn", devname, f);*/
  97. if (f < 0) {
  98. if (errno != ENOENT &&
  99.     errno != ENXIO &&
  100.     errno != ENODEV) {
  101. if (scgp->errstr)
  102. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  103. "Cannot open '%s'",
  104. devname);
  105. return (0);
  106. }
  107. } else {
  108. if (scsi_setup(scgp, f, b, t, l))
  109. nopen++;
  110. }
  111. }
  112. }
  113. }
  114. /*
  115.  * Could not open /dev/su-* or got dev=devname:b,l,l / dev=devname:@,l
  116.  * We do the apropriate tests and try our best.
  117.  */
  118. openbydev:
  119. if (nopen == 0) {
  120. if (device == NULL || device[0] == '')
  121. return (0);
  122. f = open(device, O_RDWR|O_NONBLOCK);
  123. if (f < 0)
  124. return (0);
  125. if (tlun == -2) { /* If 'lun' is not known, we reject */
  126. close(f);
  127. errno = EINVAL;
  128. return (0);
  129. }
  130. scgp->scsibus = busno = 0; /* use fake number, we cannot get it */
  131. scgp->target  = tgt = 0; /* use fake number, we cannot get it */
  132. /* 'lun' has been specified on command line */
  133. if (scsi_setup(scgp, f, busno, tgt, tlun))
  134. nopen++;
  135. }
  136. return (nopen);
  137. }
  138. EXPORT int
  139. scsi_close(scgp)
  140. SCSI *scgp;
  141. {
  142. register int f;
  143. register int b;
  144. register int t;
  145. register int l;
  146. if (scgp->local == NULL)
  147. return (-1);
  148. for (b=0; b < MAX_SCG; b++) {
  149. for (t=0; t < MAX_TGT; t++) {
  150. for (l=0; l < MAX_LUN ; l++)
  151. f = scglocal(scgp)->scgfiles[b][t][l];
  152. if (f >= 0)
  153. close(f);
  154. scglocal(scgp)->scgfiles[b][t][l] = (short)-1;
  155. }
  156. }
  157. return (0);
  158. }
  159. LOCAL BOOL
  160. scsi_setup(scgp, f, busno, tgt, tlun)
  161. SCSI *scgp;
  162. int f;
  163. int busno;
  164. int tgt;
  165. int tlun;
  166. {
  167. int Bus;
  168. int Target;
  169. int Lun;
  170. BOOL onetarget = FALSE;
  171. if (scgp->scsibus >= 0 && scgp->target >= 0 && scgp->lun >= 0)
  172. onetarget = TRUE;
  173. /*
  174.  * Unfortunately there is no way to get the right values from kernel.
  175.  */
  176. Bus = busno;
  177. Target = tgt;
  178. Lun = tlun;
  179. if (scgp->debug)
  180. printf("Bus: %d Target: %d Lun: %dn", Bus, Target, Lun);
  181. if (Bus >= MAX_SCG || Target >= 8 || Lun >= 8) {
  182. close(f);
  183. return (FALSE);
  184. }
  185. if (scglocal(scgp)->scgfiles[Bus][Target][Lun] == (short)-1)
  186. scglocal(scgp)->scgfiles[Bus][Target][Lun] = (short)f;
  187. if (onetarget) {
  188. if (Bus == busno && Target == tgt && Lun == tlun) {
  189. return (TRUE);
  190. } else {
  191. scglocal(scgp)->scgfiles[Bus][Target][Lun] = (short)-1;
  192. close(f);
  193. }
  194. }
  195. return (FALSE);
  196. }
  197. LOCAL long
  198. scsi_maxdma(scgp)
  199. SCSI *scgp;
  200. {
  201. long maxdma = MAX_DMA_BSDI;
  202. return (maxdma);
  203. }
  204. EXPORT void *
  205. scsi_getbuf(scgp, amt)
  206. SCSI *scgp;
  207. long amt;
  208. {
  209. if (amt <= 0 || amt > scsi_maxdma(scgp))
  210. return ((void *)0);
  211. if (scgp->debug)
  212. printf("scsi_getbuf: %ld bytesn", amt);
  213. scgp->bufbase = malloc((size_t)(amt));
  214. return (scgp->bufbase);
  215. }
  216. EXPORT void
  217. scsi_freebuf(scgp)
  218. SCSI *scgp;
  219. {
  220. if (scgp->bufbase)
  221. free(scgp->bufbase);
  222. scgp->bufbase = NULL;
  223. }
  224. EXPORT
  225. BOOL scsi_havebus(scgp, busno)
  226. SCSI *scgp;
  227. int busno;
  228. {
  229. register int t;
  230. register int l;
  231. if (busno < 0 || busno >= MAX_SCG)
  232. return (FALSE);
  233. if (scgp->local == NULL)
  234. return (-1);
  235. for (t=0; t < MAX_TGT; t++) {
  236. for (l=0; l < MAX_LUN ; l++)
  237. if (scglocal(scgp)->scgfiles[busno][t][l] >= 0)
  238. return (TRUE);
  239. }
  240. return (FALSE);
  241. }
  242. EXPORT
  243. int scsi_fileno(scgp, busno, tgt, tlun)
  244. SCSI *scgp;
  245. int busno;
  246. int tgt;
  247. int tlun;
  248. {
  249. if (busno < 0 || busno >= MAX_SCG ||
  250.     tgt < 0 || tgt >= MAX_TGT ||
  251.     tlun < 0 || tlun >= MAX_LUN)
  252. return (-1);
  253. if (scgp->local == NULL)
  254. return (-1);
  255. return ((int)scglocal(scgp)->scgfiles[busno][tgt][tlun]);
  256. }
  257. EXPORT int
  258. scsi_initiator_id(scgp)
  259. SCSI *scgp;
  260. {
  261. return (-1);
  262. }
  263. EXPORT
  264. int scsi_isatapi(scgp)
  265. SCSI *scgp;
  266. {
  267. return (FALSE);
  268. }
  269. EXPORT
  270. int scsireset(scgp)
  271. SCSI *scgp;
  272. {
  273. /*
  274.  * Cannot reset on BSD/OS
  275.  */
  276. return (-1);
  277. }
  278. LOCAL int
  279. scsi_send(scgp, f, sp)
  280. SCSI *scgp;
  281. int f;
  282. struct scg_cmd *sp;
  283. {
  284. scsi_user_cdb_t suc;
  285. int ret = 0;
  286. /* printf("f: %dn", f);*/
  287. if (f < 0) {
  288. sp->error = SCG_FATAL;
  289. return (0);
  290. }
  291. /* Zero the structure... */
  292. fillbytes(&suc, sizeof(suc), '');
  293. /* Read or write? */
  294. if (sp->flags & SCG_RECV_DATA) {
  295. suc.suc_flags |= SUC_READ;
  296. } else if (sp->size > 0) {
  297. suc.suc_flags |= SUC_WRITE;
  298. }
  299. suc.suc_timeout = sp->timeout;
  300. suc.suc_cdblen = sp->cdb_len;
  301. movebytes(sp->cdb.cmd_cdb, suc.suc_cdb, suc.suc_cdblen);
  302. suc.suc_datalen = sp->size;
  303. suc.suc_data = sp->addr;
  304. if (ioctl(f, SCSIRAWCDB, &suc) < 0) {
  305. ret  = -1;
  306. sp->ux_errno = geterrno();
  307. if (sp->ux_errno != ENOTTY)
  308. ret = 0;
  309. } else {
  310. sp->ux_errno = 0;
  311. if (suc.suc_sus.sus_status != STS_GOOD)
  312. sp->ux_errno = EIO;
  313. }
  314. fillbytes(&sp->scb, sizeof(sp->scb), '');
  315. fillbytes(&sp->u_sense.cmd_sense, sizeof(sp->u_sense.cmd_sense), '');
  316. #if 0
  317. /*
  318.  * Unfortunalety, BSD/OS has no idea of DMA residual count.
  319.  */
  320. sp->resid = req.datalen - req.datalen_used;
  321. sp->sense_count = req.senselen_used;
  322. #else
  323. sp->resid = 0;
  324. sp->sense_count = sizeof(suc.suc_sus.sus_sense);
  325. #endif
  326. if (sp->sense_count > SCG_MAX_SENSE)
  327. sp->sense_count = SCG_MAX_SENSE;
  328. movebytes(suc.suc_sus.sus_sense, sp->u_sense.cmd_sense, sp->sense_count);
  329. sp->u_scb.cmd_scb[0] = suc.suc_sus.sus_status;
  330. switch (suc.suc_sus.sus_status) {
  331. case STS_GOOD:
  332. sp->error = SCG_NO_ERROR; break;
  333. case STS_CMD_TERMINATED:sp->error = SCG_TIMEOUT; break;
  334. case STS_BUSY: sp->error = SCG_RETRYABLE; break;
  335. case STS_CHECKCOND: sp->error = SCG_RETRYABLE; break;
  336. case STS_QUEUE_FULL: sp->error = SCG_RETRYABLE; break;
  337. default: sp->error = SCG_FATAL; break;
  338. }
  339. return (ret);
  340. }
  341. #define sense u_sense.Sense
  342. #undef scsi_sense
  343. #undef scsi_inquiry