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

SCSI/ASPI

开发平台:

MultiPlatform

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