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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)scsi-linux-sg.c 1.37 99/09/07 Copyright 1997 J. Schilling */
  2. #ifndef lint
  3. static char __sccsid[] =
  4. "@(#)scsi-linux-sg.c 1.37 99/09/07 Copyright 1997 J. Schilling";
  5. #endif
  6. /*
  7.  * Interface for Linux generic SCSI implementation (sg).
  8.  *
  9.  * This is the interface for the broken Linux SCSI generic driver.
  10.  * This is a hack, that tries to emulate the functionality
  11.  * of the scg driver.
  12.  *
  13.  * Design flaws of the sg driver:
  14.  * - cannot see if SCSI command could not be send
  15.  * - cannot get SCSI status byte
  16.  * - cannot get real dma count of tranfer
  17.  * - cannot get number of bytes valid in auto sense data
  18.  * - to few data in auto sense (CCS/SCSI-2/SCSI-3 needs >= 18)
  19.  *
  20.  * This code contains support for the sg driver version 2
  21.  *
  22.  * Copyright (c) 1997 J. Schilling
  23.  */
  24. /*
  25.  * This program is free software; you can redistribute it and/or modify
  26.  * it under the terms of the GNU General Public License as published by
  27.  * the Free Software Foundation; either version 2, or (at your option)
  28.  * any later version.
  29.  *
  30.  * This program is distributed in the hope that it will be useful,
  31.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  32.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  33.  * GNU General Public License for more details.
  34.  *
  35.  * You should have received a copy of the GNU General Public License
  36.  * along with this program; see the file COPYING.  If not, write to
  37.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  38.  */
  39. #include <linux/version.h>
  40. #ifndef LINUX_VERSION_CODE /* Very old kernel? */
  41. # define LINUX_VERSION_CODE 0
  42. #endif
  43. #if LINUX_VERSION_CODE >= 0x01031a /* <linux/scsi.h> introduced in 1.3.26 */
  44. #if LINUX_VERSION_CODE >= 0x020000 /* <scsi/scsi.h> introduced somewhere. */
  45. /* Need to fine tune the ifdef so we get the transition point right. */
  46. #include <scsi/scsi.h>
  47. #else
  48. #include <linux/scsi.h>
  49. #endif
  50. #else
  51. #define __KERNEL__
  52. #include <linux/fs.h>
  53. #undef __KERNEL__
  54. #include "block/blk.h"
  55. #include "scsi/scsi.h"
  56. #endif
  57. #include "scsi/sg.h"
  58. #ifndef SCSI_IOCTL_GET_BUS_NUMBER
  59. #define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
  60. #endif
  61. /*
  62.  * XXX There must be a better way than duplicating things from system include
  63.  * XXX files. This is stolen from /usr/src/linux/drivers/scsi/scsi.h
  64.  */
  65. #ifndef DID_OK
  66. #define DID_OK          0x00 /* NO error                                */
  67. #define DID_NO_CONNECT  0x01 /* Couldn't connect before timeout period  */
  68. #define DID_BUS_BUSY    0x02 /* BUS stayed busy through time out period */
  69. #define DID_TIME_OUT    0x03 /* TIMED OUT for other reason              */
  70. #define DID_BAD_TARGET  0x04 /* BAD target.                             */
  71. #define DID_ABORT       0x05 /* Told to abort for some other reason     */
  72. #define DID_PARITY      0x06 /* Parity error                            */
  73. #define DID_ERROR       0x07 /* Internal error                          */
  74. #define DID_RESET       0x08 /* Reset by somebody.                      */
  75. #define DID_BAD_INTR    0x09 /* Got an interrupt we weren't expecting.  */ 
  76. #endif
  77. /*
  78.  *  These indicate the error that occurred, and what is available.
  79.  */
  80. #ifndef DRIVER_BUSY
  81. #define DRIVER_BUSY         0x01
  82. #define DRIVER_SOFT         0x02
  83. #define DRIVER_MEDIA        0x03
  84. #define DRIVER_ERROR        0x04
  85.  
  86. #define DRIVER_INVALID      0x05
  87. #define DRIVER_TIMEOUT      0x06
  88. #define DRIVER_HARD         0x07
  89. #define DRIVER_SENSE        0x08
  90. #endif
  91. /*
  92.  * XXX Should add extra space in buscookies and scgfiles for a "PP bus"
  93.  * XXX and for two "ATAPI busses".
  94.  */
  95. #define MAX_SCG 16 /* Max # of SCSI controllers */
  96. #define MAX_TGT 16
  97. #define MAX_LUN 8
  98. struct scg_local {
  99. int scgfile; /* Used for SG_GET_BUFSIZE ioctl()*/
  100. short scgfiles[MAX_SCG][MAX_TGT][MAX_LUN];
  101. short buscookies[MAX_SCG];
  102. int pgbus;
  103. int pack_id; /* Should be a random number */
  104. char *SCSIbuf;
  105. };
  106. #define scglocal(p) ((struct scg_local *)((p)->local)) 
  107. #ifdef SG_BIG_BUFF
  108. #define MAX_DMA_LINUX SG_BIG_BUFF /* Defined in include/scsi/sg.h */
  109. #else
  110. #define MAX_DMA_LINUX (4*1024) /* Old Linux versions */
  111. #endif
  112. #ifndef SG_MAX_SENSE
  113. # define SG_MAX_SENSE 16 /* Too small for CCS / SCSI-2 */
  114. #endif /* But cannot be changed */
  115. #if !defined(__i386) && !defined(i386) && !defined(mc68000)
  116. #define MISALIGN
  117. #endif
  118. /*#define MISALIGN*/
  119. /*#undef SG_GET_BUFSIZE*/
  120. #if defined(USE_PG) && !defined(USE_PG_ONLY)
  121. #include "scsi-linux-pg.c"
  122. #endif
  123. #ifdef MISALIGN
  124. LOCAL int scsi_getint __PR((int *ip));
  125. #endif
  126. LOCAL int scsi_send __PR((SCSI *scgp, int f, struct scg_cmd *sp));
  127. LOCAL BOOL sg_setup __PR((SCSI *scgp, int f, int busno, int tgt, int tlun));
  128. LOCAL void sg_initdev __PR((SCSI *scgp, int f));
  129. LOCAL int sg_mapbus __PR((SCSI *scgp, int busno, int ino));
  130. LOCAL BOOL sg_mapdev __PR((SCSI *scgp, int f, int *busp, int *tgtp, int *lunp,
  131. int *chanp, int *inop));
  132. LOCAL void sg_settimeout __PR((int f, int timeout));
  133. EXPORT int
  134. scsi_open(scgp, device, busno, tgt, tlun)
  135. SCSI *scgp;
  136. char *device;
  137. int busno;
  138. int tgt;
  139. int tlun;
  140. {
  141. register int f;
  142. register int i;
  143. register int b;
  144. register int t;
  145. register int l;
  146. register int nopen = 0;
  147. char devname[64];
  148. if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) {
  149. errno = EINVAL;
  150. if (scgp->errstr)
  151. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  152. "Illegal value for busno, target or lun '%d,%d,%d'",
  153. busno, tgt, tlun);
  154. return (-1);
  155. }
  156. if (scgp->local == NULL) {
  157. scgp->local = malloc(sizeof(struct scg_local));
  158. if (scgp->local == NULL)
  159. return (0);
  160. scglocal(scgp)->scgfile = -1;
  161. scglocal(scgp)->pgbus = -2;
  162. scglocal(scgp)->SCSIbuf = (char *)-1;
  163. scglocal(scgp)->pack_id = 5;
  164. for (b=0; b < MAX_SCG; b++) {
  165. scglocal(scgp)->buscookies[b] = (short)-1;
  166. for (t=0; t < MAX_TGT; t++) {
  167. for (l=0; l < MAX_LUN ; l++)
  168. scglocal(scgp)->scgfiles[b][t][l] = (short)-1;
  169. }
  170. }
  171. }
  172. if ((device != NULL && *device != '') || (busno == -2 && tgt == -2))
  173. goto openbydev;
  174. for (i=0; i < 32; i++) {
  175. sprintf(devname, "/dev/sg%d", i);
  176. f = open(devname, 2);
  177. if (f < 0) {
  178. if (errno != EACCES && errno != ENOENT && errno != ENXIO && errno != ENODEV) {
  179. if (scgp->errstr)
  180. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  181. "Cannot open '%s'", devname);
  182. return (0);
  183. }
  184. } else {
  185. if (sg_setup(scgp, f, busno, tgt, tlun))
  186. return (++nopen);
  187. if (busno < 0 && tgt < 0 && tlun < 0)
  188. nopen++;
  189. }
  190. }
  191. if (nopen == 0) for (i=0; i <= 25; i++) {
  192. sprintf(devname, "/dev/sg%c", i+'a');
  193. f = open(devname, 2);
  194. if (f < 0) {
  195. if (errno != ENOENT && errno != ENXIO && errno != ENODEV) {
  196. if (scgp->errstr)
  197. js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
  198. "Cannot open '%s'", devname);
  199. return (0);
  200. }
  201. } else {
  202. if (sg_setup(scgp, f, busno, tgt, tlun))
  203. return (++nopen);
  204. if (busno < 0 && tgt < 0 && tlun < 0)
  205. nopen++;
  206. }
  207. }
  208. openbydev:
  209. if (device != NULL && *device != '') {
  210. f = open(device, 2);
  211. if (f < 0 && errno == ENOENT)
  212. goto openpg;
  213. if (!sg_mapdev(scgp, f, &busno, &tgt, &tlun, 0, 0)) {
  214. close(f);
  215. goto openpg;
  216. }
  217. if (scgp->scsibus < 0)
  218. scgp->scsibus = busno;
  219. if (scgp->target < 0)
  220. scgp->target = tgt;
  221. if (scgp->lun < 0)
  222. scgp->lun = tlun;
  223. if (sg_setup(scgp, f, busno, tgt, tlun))
  224. return (++nopen);
  225. }
  226. openpg:
  227. #ifdef USE_PG
  228. nopen += pg_open(scgp, device, busno, tgt, tlun);
  229. #endif
  230. if (scgp->debug) for (b=0; b < MAX_SCG; b++) {
  231. printf("Bus: %d cookie: %Xn", b, scglocal(scgp)->buscookies[b]);
  232. for (t=0; t < MAX_TGT; t++) {
  233. for (l=0; l < MAX_LUN ; l++)
  234. if (scglocal(scgp)->scgfiles[b][t][l] != (short)-1)
  235. printf("file (%d,%d,%d): %dn",
  236. b, t, l, scglocal(scgp)->scgfiles[b][t][l]);
  237. }
  238. }
  239. return (nopen);
  240. }
  241. EXPORT int
  242. scsi_close(scgp)
  243. SCSI *scgp;
  244. {
  245. register int f;
  246. register int b;
  247. register int t;
  248. register int l;
  249. if (scgp->local == NULL)
  250. return (-1);
  251. for (b=0; b < MAX_SCG; b++) {
  252. if (b == scglocal(scgp)->pgbus)
  253. continue;
  254. scglocal(scgp)->buscookies[b] = (short)-1;
  255. for (t=0; t < MAX_TGT; t++) {
  256. for (l=0; l < MAX_LUN ; l++) {
  257. f = scglocal(scgp)->scgfiles[b][t][l];
  258. if (f >= 0)
  259. close(f);
  260. scglocal(scgp)->scgfiles[b][t][l] = (short)-1;
  261. }
  262. }
  263. }
  264. #ifdef USE_PG
  265. pg_close(scgp);
  266. #endif
  267. return (0);
  268. }
  269. LOCAL BOOL
  270. sg_setup(scgp, f, busno, tgt, tlun)
  271. SCSI *scgp;
  272. int f;
  273. int busno;
  274. int tgt;
  275. int tlun;
  276. {
  277. int n;
  278. int Chan;
  279. int Ino;
  280. int Bus;
  281. int Target;
  282. int Lun;
  283. BOOL onetarget = FALSE;
  284. if (scgp->scsibus >= 0 && scgp->target >= 0 && scgp->lun >= 0)
  285. onetarget = TRUE;
  286. sg_mapdev(scgp, f, &Bus, &Target, &Lun, &Chan, &Ino);
  287. /*
  288.  * For old kernels try to make the best guess.
  289.  */
  290. Ino |= Chan << 8;
  291. n = sg_mapbus(scgp, Bus, Ino);
  292. if (Bus == -1) {
  293. Bus = n;
  294. if (scgp->debug)
  295. printf("SCSI Bus: %d (mapped from %d)n", Bus, Ino);
  296. }
  297. if (Bus < 0 || Bus >= MAX_SCG || Target < 0 || Target >= MAX_TGT ||
  298. Lun < 0 || Lun >= MAX_LUN) {
  299. return (FALSE);
  300. }
  301. if (scglocal(scgp)->scgfiles[Bus][Target][Lun] == (short)-1)
  302. scglocal(scgp)->scgfiles[Bus][Target][Lun] = (short)f;
  303. if (onetarget) {
  304. if (Bus == busno && Target == tgt && Lun == tlun) {
  305. sg_initdev(scgp, f);
  306. scglocal(scgp)->scgfile = f; /* remember file for ioctl's */
  307. return (TRUE);
  308. } else {
  309. scglocal(scgp)->scgfiles[Bus][Target][Lun] = (short)-1;
  310. close(f);
  311. }
  312. } else {
  313. sg_initdev(scgp, f);
  314. if (scglocal(scgp)->scgfile < 0)
  315. scglocal(scgp)->scgfile = f; /* remember file for ioctl's */
  316. }
  317. return (FALSE);
  318. }
  319. LOCAL void
  320. sg_initdev(scgp, f)
  321. SCSI *scgp;
  322. int f;
  323. {
  324. struct sg_rep {
  325. struct sg_header hd;
  326. unsigned char rbuf[100];
  327. } sg_rep;
  328. int n;
  329. /* Eat any unwanted garbage from prior use of this device */
  330. n = fcntl(f, F_GETFL); /* Be very proper about this */
  331. fcntl(f, F_SETFL, n|O_NONBLOCK);
  332. fillbytes((caddr_t)&sg_rep, sizeof(struct sg_header), '');
  333. sg_rep.hd.reply_len = sizeof(struct sg_header);
  334. while (read(f, &sg_rep, sizeof(sg_rep)) >= 0 || errno != EAGAIN)
  335. ;
  336. fcntl(f, F_SETFL, n);
  337. sg_settimeout(f, scgp->deftimeout);
  338. }
  339. LOCAL int
  340. sg_mapbus(scgp, busno, ino)
  341. SCSI *scgp;
  342. int busno;
  343. int ino;
  344. {
  345. register int i;
  346. if (busno >= 0 && busno < MAX_SCG) {
  347. /*
  348.  * SCSI_IOCTL_GET_BUS_NUMBER worked.
  349.  * Now we have the problem that Linux does not properly number
  350.  * SCSI busses. The Bus number that Linux creates really is
  351.  * the controller (card) number. I case of multi SCSI bus
  352.  * cards we are lost.
  353.  */
  354. if (scglocal(scgp)->buscookies[busno] == (short)-1) {
  355. scglocal(scgp)->buscookies[busno] = ino;
  356. return (busno);
  357. }
  358. if (scglocal(scgp)->buscookies[busno] != (short)ino)
  359. errmsgno(EX_BAD, "Warning Linux Bus mapping botch.n");
  360. return (busno);
  361. } else for (i=0; i < MAX_SCG; i++) {
  362. if (scglocal(scgp)->buscookies[i] == (short)-1) {
  363. scglocal(scgp)->buscookies[i] = ino;
  364. return (i);
  365. }
  366. if (scglocal(scgp)->buscookies[i] == ino)
  367. return (i);
  368. }
  369. return (0);
  370. }
  371. LOCAL BOOL
  372. sg_mapdev(scgp, f, busp, tgtp, lunp, chanp, inop)
  373. SCSI *scgp;
  374. int f;
  375. int *busp;
  376. int *tgtp;
  377. int *lunp;
  378. int *chanp;
  379. int *inop;
  380. {
  381. struct sg_id {
  382. long l1; /* target | lun << 8 | channel << 16 | low_ino << 24 */
  383. long l2; /* Unique id */
  384. } sg_id;
  385. int Chan;
  386. int Ino;
  387. int Bus;
  388. int Target;
  389. int Lun;
  390. if (ioctl(f, SCSI_IOCTL_GET_IDLUN, &sg_id))
  391. return (FALSE);
  392. if (scgp->debug)
  393. printf("l1: 0x%lX l2: 0x%lXn", sg_id.l1, sg_id.l2);
  394. if (ioctl(f, SCSI_IOCTL_GET_BUS_NUMBER, &Bus) < 0) {
  395. Bus = -1;
  396. }
  397. Target = sg_id.l1 & 0xFF;
  398. Lun = (sg_id.l1 >> 8) & 0xFF;
  399. Chan = (sg_id.l1 >> 16) & 0xFF;
  400. Ino = (sg_id.l1 >> 24) & 0xFF;
  401. if (scgp->debug) {
  402. printf("Bus: %d Target: %d Lun: %d Chan: %d Ino: %dn",
  403. Bus, Target, Lun, Chan, Ino);
  404. }
  405. *busp = Bus;
  406. *tgtp = Target;
  407. *lunp = Lun;
  408. if (chanp)
  409. *chanp = Chan;
  410. if (inop)
  411. *inop = Ino;
  412. return (TRUE);
  413. }
  414. LOCAL long
  415. scsi_maxdma(scgp)
  416. SCSI *scgp;
  417. {
  418. long maxdma = MAX_DMA_LINUX;
  419. #ifdef SG_GET_BUFSIZE
  420. /*
  421.  * We assume that all /dev/sg instances use the same
  422.  * maximum buffer size.
  423.  */
  424. if ((maxdma = ioctl(scglocal(scgp)->scgfile, SG_GET_BUFSIZE, 0)) < 0) {
  425. if (scglocal(scgp)->scgfile >= 0) {
  426. maxdma = MAX_DMA_LINUX;
  427. }
  428. }
  429. #endif
  430. #ifdef USE_PG
  431. if (scgp->scsibus == scglocal(scgp)->pgbus)
  432. return (pg_maxdma(scgp));
  433. if ((scgp->scsibus < 0) && (pg_maxdma(scgp) < maxdma))
  434. return (pg_maxdma(scgp));
  435. #endif
  436. return (maxdma);
  437. }
  438. EXPORT void *
  439. scsi_getbuf(scgp, amt)
  440. SCSI *scgp;
  441. long amt;
  442. {
  443. char *ret;
  444. if (amt <= 0 || amt > scsi_maxdma(scgp))
  445. return ((void *)0);
  446. if (scgp->debug)
  447. printf("scsi_getbuf: %ld bytesn", amt);
  448. /*
  449.  * For performance reason, we allocate pagesize()
  450.  * bytes before the SCSI buffer to avoid
  451.  * copying the whole buffer contents when
  452.  * setting up the /dev/sg data structures.
  453.  */
  454. ret = valloc((size_t)(amt+getpagesize()));
  455. if (ret == NULL)
  456. return (ret);
  457. scgp->bufbase = ret;
  458. ret += getpagesize();
  459. scglocal(scgp)->SCSIbuf = ret;
  460. return ((void *)ret);
  461. }
  462. EXPORT void
  463. scsi_freebuf(scgp)
  464. SCSI *scgp;
  465. {
  466. if (scgp->bufbase)
  467. free(scgp->bufbase);
  468. scgp->bufbase = NULL;
  469. }
  470. EXPORT
  471. BOOL scsi_havebus(scgp, busno)
  472. SCSI *scgp;
  473. int busno;
  474. {
  475. register int t;
  476. register int l;
  477. if (busno < 0 || busno >= MAX_SCG)
  478. return (FALSE);
  479. if (scgp->local == NULL)
  480. return (FALSE);
  481. for (t=0; t < MAX_TGT; t++) {
  482. for (l=0; l < MAX_LUN ; l++)
  483. if (scglocal(scgp)->scgfiles[busno][t][l] >= 0)
  484. return (TRUE);
  485. }
  486. return (FALSE);
  487. }
  488. EXPORT
  489. int scsi_fileno(scgp, busno, tgt, tlun)
  490. SCSI *scgp;
  491. int busno;
  492. int tgt;
  493. int tlun;
  494. {
  495. if (busno < 0 || busno >= MAX_SCG ||
  496.     tgt < 0 || tgt >= MAX_TGT ||
  497.     tlun < 0 || tlun >= MAX_LUN)
  498. return (-1);
  499. if (scgp->local == NULL)
  500. return (-1);
  501. return ((int)scglocal(scgp)->scgfiles[busno][tgt][tlun]);
  502. }
  503. EXPORT int
  504. scsi_initiator_id(scgp)
  505. SCSI *scgp;
  506. {
  507. #ifdef USE_PG
  508. if (scgp->scsibus == scglocal(scgp)->pgbus)
  509. return (pg_initiator_id(scgp));
  510. #endif
  511. return (-1);
  512. }
  513. EXPORT
  514. int scsi_isatapi(scgp)
  515. SCSI *scgp;
  516. {
  517. #ifdef USE_PG
  518. if (scgp->scsibus == scglocal(scgp)->pgbus)
  519. return (pg_isatapi(scgp));
  520. #endif
  521. #ifdef SG_EMULATED_HOST
  522. {
  523. int emulated = FALSE;
  524. int f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun);
  525. if (ioctl(f, SG_EMULATED_HOST, &emulated) >= 0)
  526. return (emulated != 0);
  527. }
  528. #endif
  529. return (-1);
  530. }
  531. EXPORT
  532. int scsireset(scgp)
  533. SCSI *scgp;
  534. {
  535. #ifdef USE_PG
  536. if (scgp->scsibus == scglocal(scgp)->pgbus)
  537. return (pg_reset(scgp));
  538. #endif
  539. /*
  540.  * Do we have a SCSI reset in the Linux sg driver?
  541.  */
  542. return (-1);
  543. }
  544. LOCAL void
  545. sg_settimeout(f, tmo)
  546. int f;
  547. int tmo;
  548. {
  549. tmo *= HZ;
  550. if (tmo)
  551. tmo += HZ/2;
  552. if (ioctl(f, SG_SET_TIMEOUT, &tmo) < 0)
  553. comerr("Cannot set SG_SET_TIMEOUT.n");
  554. }
  555. /*
  556.  * Get misaligned int.
  557.  * Needed for all recent processors (sparc/ppc/alpha)
  558.  * because the /dev/sg design forces us to do misaligned
  559.  * reads of integers.
  560.  */
  561. #ifdef MISALIGN
  562. LOCAL int
  563. scsi_getint(ip)
  564. int *ip;
  565. {
  566.  int ret;
  567. register char *cp = (char *)ip;
  568. register char *tp = (char *)&ret;
  569. register int i;
  570. for (i = sizeof(int); --i >= 0; )
  571. *tp++ = *cp++;
  572. return (ret);
  573. }
  574. #define GETINT(a) scsi_getint(&(a))
  575. #else
  576. #define GETINT(a) (a)
  577. #endif
  578. LOCAL int
  579. scsi_send(scgp, f, sp)
  580. SCSI *scgp;
  581. int f;
  582. struct scg_cmd *sp;
  583. {
  584. struct sg_rq *sgp;
  585. struct sg_rq *sgp2;
  586. int i;
  587. int pack_len;
  588. int reply_len;
  589. int amt = sp->cdb_len;
  590. struct sg_rq {
  591. struct sg_header hd;
  592. unsigned char buf[MAX_DMA_LINUX+SCG_MAX_CMD];
  593. } sg_rq;
  594. #ifdef SG_GET_BUFSIZE /* We may use a 'sg' version 2 driver */
  595. char driver_byte;
  596. char host_byte;
  597. char msg_byte;
  598. char status_byte;
  599. #endif
  600. if (f < 0) {
  601. sp->error = SCG_FATAL;
  602. return (0);
  603. }
  604. #ifdef USE_PG
  605. if (scgp->scsibus == scglocal(scgp)->pgbus)
  606. return (pg_send(scgp, f, sp));
  607. #endif
  608. if (sp->timeout != scgp->deftimeout)
  609. sg_settimeout(f, sp->timeout);
  610. sgp2 = sgp = &sg_rq;
  611. if (sp->addr == scglocal(scgp)->SCSIbuf) {
  612. sgp = (struct sg_rq *)
  613. (scglocal(scgp)->SCSIbuf - (sizeof(struct sg_header) + amt));
  614. sgp2 = (struct sg_rq *)
  615. (scglocal(scgp)->SCSIbuf - (sizeof(struct sg_header)));
  616. } else {
  617. if (scgp->debug) {
  618. printf("DMA addr: 0x%8.8lX size: %d - using copy buffern",
  619. (long)sp->addr, sp->size);
  620. }
  621. if (sp->size > (int)(sizeof(sg_rq.buf) - SCG_MAX_CMD)) {
  622. errno = ENOMEM;
  623. return (-1);
  624. }
  625. }
  626. /*
  627.  * This is done to avoid misaligned access of sgp->some_int
  628.  */
  629. pack_len = sizeof(struct sg_header) + amt;
  630. reply_len = sizeof(struct sg_header);
  631. if (sp->flags & SCG_RECV_DATA) {
  632. reply_len += sp->size;
  633. } else {
  634. pack_len += sp->size;
  635. }
  636. #ifdef MISALIGN
  637. /*
  638.  * sgp->some_int may be misaligned if (sp->addr == SCSIbuf)
  639.  * This is no problem on Intel porocessors, however
  640.  * all other processors don't like it.
  641.  * sizeof(struct sg_header) + amt is usually not a multiple of
  642.  * sizeof(int). For this reason, we fill in the values into sg_rq
  643.  * which is always corectly aligned and then copy it to the real
  644.  * location if this location differs from sg_rq.
  645.  * Never read/write directly to sgp->some_int !!!!!
  646.  */
  647. fillbytes((caddr_t)&sg_rq, sizeof(struct sg_header), '');
  648. sg_rq.hd.pack_len = pack_len;
  649. sg_rq.hd.reply_len = reply_len;
  650. sg_rq.hd.pack_id = scglocal(scgp)->pack_id++;
  651. /* sg_rq.hd.result = 0; not needed because of fillbytes() */
  652. if ((caddr_t)&sg_rq != (caddr_t)sgp)
  653. movebytes((caddr_t)&sg_rq, (caddr_t)sgp, sizeof(struct sg_header));
  654. #else
  655. fillbytes((caddr_t)sgp, sizeof(struct sg_header), '');
  656. sgp->hd.pack_len = pack_len;
  657. sgp->hd.reply_len = reply_len;
  658. sgp->hd.pack_id = scglocal(scgp)->pack_id++;
  659. /* sgp->hd.result = 0; not needed because of fillbytes() */
  660. #endif
  661. if (amt == 12)
  662. sgp->hd.twelve_byte = 1;
  663. for (i = 0; i < amt; i++ ) {
  664. sgp->buf[i] = sp->cdb.cmd_cdb[i];;
  665. }
  666. if (!(sp->flags & SCG_RECV_DATA)) {
  667. if ((void *)sp->addr != (void *)&sgp->buf[amt])
  668. movebytes(sp->addr, &sgp->buf[amt], sp->size);
  669. amt += sp->size;
  670. }
  671. #ifdef SG_GET_BUFSIZE
  672. sgp->hd.want_new  = 1; /* Order new behaviour */
  673. sgp->hd.cdb_len   = sp->cdb_len; /* Set CDB length */
  674. if (sp->sense_len > SG_MAX_SENSE)
  675. sgp->hd.sense_len = SG_MAX_SENSE;
  676. else
  677. sgp->hd.sense_len = sp->sense_len;
  678. #endif
  679. i = sizeof(struct sg_header) + amt;
  680. if ((amt = write(f, sgp, i)) < 0) { /* write */
  681. sg_settimeout(f, scgp->deftimeout);
  682. return (-1);
  683. } else if (amt != i) {
  684. errmsg("scsi_send(%s) wrote %d bytes (expected %d).n",
  685. scgp->cmdname, amt, i);
  686. }
  687. if (sp->addr == scglocal(scgp)->SCSIbuf) {
  688. movebytes(sgp, sgp2, sizeof(struct sg_header));
  689. sgp = sgp2;
  690. }
  691. sgp->hd.sense_buffer[0] = 0;
  692. if ((amt = read(f, sgp, reply_len)) < 0) { /* read */
  693. sg_settimeout(f, scgp->deftimeout);
  694. return (-1);
  695. }
  696. if (sp->flags & SCG_RECV_DATA && ((void *)sgp->buf != (void *)sp->addr)) {
  697. movebytes(sgp->buf, sp->addr, sp->size);
  698. }
  699. sp->ux_errno = GETINT(sgp->hd.result); /* Unaligned read */
  700. sp->error = SCG_NO_ERROR;
  701. #ifdef SG_GET_BUFSIZE
  702. if (sgp->hd.grant_new) {
  703. sp->sense_count = sgp->hd.sense_len;
  704. pack_len    = GETINT(sgp->hd.sg_cmd_status); /* Unaligned read */
  705. driver_byte = (pack_len  >> 24) & 0xFF;
  706. host_byte   = (pack_len  >> 16) & 0xFF;
  707. msg_byte    = (pack_len  >> 8) & 0xFF;
  708. status_byte =  pack_len  & 0xFF;
  709. switch (host_byte) {
  710. case DID_OK:
  711. if ((driver_byte & DRIVER_SENSE ||
  712.     sgp->hd.sense_buffer[0] != 0)
  713. && status_byte == 0) {
  714. /*
  715.  * The Linux SCSI system up to 2.1.xx
  716.  * trashes the status byte in the
  717.  * kernel. This is true at least for
  718.  * ide-scsi emulation. Until this gets
  719.  * fixed, we need this hack.
  720.  */
  721. sp->error = SCG_RETRYABLE;
  722. status_byte = ST_CHK_COND;
  723. if (sgp->hd.sense_len == 0)
  724. sgp->hd.sense_len = SG_MAX_SENSE;
  725. }
  726. break;
  727. case DID_NO_CONNECT: /* Arbitration won, retry NO_CONNECT? */
  728. case DID_BAD_TARGET:
  729. sp->error = SCG_FATAL;
  730. break;
  731. case DID_TIME_OUT:
  732. sp->error = SCG_TIMEOUT;
  733. break;
  734. default:
  735. sp->error = SCG_RETRYABLE;
  736. if ((driver_byte & DRIVER_SENSE ||
  737.     sgp->hd.sense_buffer[0] != 0)
  738. && status_byte == 0)
  739. status_byte = ST_CHK_COND;
  740. if (status_byte != 0 && sgp->hd.sense_len == 0)
  741. sgp->hd.sense_len = SG_MAX_SENSE;
  742. break;
  743. }
  744. if ((host_byte != DID_OK || status_byte != 0) && sp->ux_errno == 0)
  745. sp->ux_errno = EIO;
  746. sp->u_scb.cmd_scb[0] = status_byte;
  747. if (status_byte & ST_CHK_COND) {
  748. sp->sense_count = sgp->hd.sense_len;
  749. movebytes(sgp->hd.sense_buffer, sp->u_sense.cmd_sense, sp->sense_count);
  750. }
  751. } else
  752. #endif
  753. {
  754. if (GETINT(sgp->hd.result) == EBUSY) { /* Unaligned read */
  755. struct timeval to;
  756. to.tv_sec = sp->timeout;
  757. to.tv_usec = 500000;
  758. scsitimes(scgp);
  759. if (scgp->cmdstop->tv_sec < to.tv_sec ||
  760.     (scgp->cmdstop->tv_sec == to.tv_sec &&
  761. scgp->cmdstop->tv_usec < to.tv_usec)) {
  762. sp->ux_errno = 0;
  763. sp->error = SCG_TIMEOUT; /* a timeout */
  764. } else {
  765. sp->error = SCG_RETRYABLE; /* may be BUS_BUSY */
  766. }
  767. }
  768. if (sp->flags & SCG_RECV_DATA)
  769. sp->resid = (sp->size + sizeof(struct sg_header)) - amt;
  770. else
  771. sp->resid = 0; /* sg version1 cannot return DMA resid count */
  772. if (sgp->hd.sense_buffer[0] != 0) {
  773. sp->error = SCG_RETRYABLE;
  774. sp->scb.chk = 1;
  775. sp->sense_count = SG_MAX_SENSE;
  776. movebytes(sgp->hd.sense_buffer, sp->u_sense.cmd_sense, sp->sense_count);
  777. if (sp->ux_errno == 0)
  778. sp->ux_errno = EIO;
  779. }
  780. }
  781. if (scgp->verbose > 0 && scgp->debug) {
  782. #ifdef SG_GET_BUFSIZE
  783. printf("status: 0x%08X pack_len: %d, reply_len: %d pack_id: %d result: %d wn: %d gn: %d cdb_len: %d sense_len: %d sense[0]: %02Xn",
  784. GETINT(sgp->hd.sg_cmd_status),
  785. GETINT(sgp->hd.pack_len),
  786. GETINT(sgp->hd.reply_len),
  787. GETINT(sgp->hd.pack_id),
  788. GETINT(sgp->hd.result),
  789. sgp->hd.want_new,
  790. sgp->hd.grant_new,
  791. sgp->hd.cdb_len,
  792. sgp->hd.sense_len,
  793. sgp->hd.sense_buffer[0]);
  794. #else
  795. printf("pack_len: %d, reply_len: %d pack_id: %d result: %d sense[0]: %02Xn",
  796. GETINT(sgp->hd.pack_len),
  797. GETINT(sgp->hd.reply_len),
  798. GETINT(sgp->hd.pack_id),
  799. GETINT(sgp->hd.result),
  800. sgp->hd.sense_buffer[0]);
  801. #endif
  802. #ifdef DEBUG
  803. printf("sense: ");
  804. for (i=0; i < 16; i++)
  805. printf("%02X ", sgp->hd.sense_buffer[i]);
  806. printf("n");
  807. #endif
  808. }
  809. if (sp->timeout != scgp->deftimeout)
  810. sg_settimeout(f, scgp->deftimeout);
  811. return 0;
  812. }