1 /* @(#)scsi-linux-pg.c	1.46 11/03/07 Copyright 1997 J. Schilling */
2 #ifndef lint
3 static	char ___sccsid[] =
4 	"@(#)scsi-linux-pg.c	1.46 11/03/07 Copyright 1997 J. Schilling";
5 #endif
6 /*
7  *	Interface for the Linux PARIDE implementation.
8  *
9  *	We emulate the functionality of the scg driver, via the pg driver.
10  *
11  *	Warning: you may change this source, but if you do that
12  *	you need to change the _scg_version and _scg_auth* string below.
13  *	You may not return "schily" for an SCG_AUTHOR request anymore.
14  *	Choose your name instead of "schily" and make clear that the version
15  *	string is related to a modified source.
16  *
17  *	Copyright (c) 1997  J. Schilling
18  *	Copyright (c) 1998  Grant R. Guenther	<grant@torque.net>
19  */
20 /*
21  * The contents of this file are subject to the terms of the
22  * Common Development and Distribution License, Version 1.0 only
23  * (the "License").  You may not use this file except in compliance
24  * with the License.
25  *
26  * See the file CDDL.Schily.txt in this distribution for details.
27  * A copy of the CDDL is also available via the Internet at
28  * http://www.opensource.org/licenses/cddl1.txt
29  *
30  * The following exceptions apply:
31  * CDDL �3.6 needs to be replaced by: "You may create a Larger Work by
32  * combining Covered Software with other code if all other code is governed by
33  * the terms of a license that is OSI approved (see www.opensource.org) and
34  * you may distribute the Larger Work as a single product. In such a case,
35  * You must make sure the requirements of this License are fulfilled for
36  * the Covered Software."
37  *
38  * When distributing Covered Code, include this CDDL HEADER in each
39  * file and include the License file CDDL.Schily.txt from this distribution.
40  */
41 
42 #include <string.h>
43 #ifdef	HAVE_LINUX_PG_H
44 #include <linux/pg.h>
45 #else
46 #include "pg.h"		/* Use local version as Linux sometimes doesn't have */
47 #endif			/* installed. Now libscg always supports PP SCSI    */
48 
49 /*
50  *	Warning: you may change this source, but if you do that
51  *	you need to change the _scg_version and _scg_auth* string below.
52  *	You may not return "schily" for an SCG_AUTHOR request anymore.
53  *	Choose your name instead of "schily" and make clear that the version
54  *	string is related to a modified source.
55  */
56 LOCAL	char	_scg_trans_version_pg[] = "scsi-linux-pg.c-1.46";	/* The version for this transport*/
57 
58 #ifdef	USE_PG_ONLY
59 
60 #define	MAX_SCG		1	/* Max # of SCSI controllers */
61 #define	MAX_TGT		8
62 #define	MAX_LUN		8
63 
64 struct scg_local {
65 	short	scgfiles[MAX_SCG][MAX_TGT][MAX_LUN];
66 	short	buscookies[MAX_SCG];
67 	int	pgbus;
68 	char	*SCSIbuf;
69 };
70 #define	scglocal(p)	((struct scg_local *)((p)->local))
71 
72 #else
73 
74 #define	scgo_version	pg_version
75 #define	scgo_help	pg_help
76 #define	scgo_open	pg_open
77 #define	scgo_close	pg_close
78 #define	scgo_send	pg_send
79 #define	scgo_maxdma	pg_maxdma
80 #define	scgo_initiator_id pg_initiator_id
81 #define	scgo_isatapi	pg_isatapi
82 #define	scgo_reset	pg_reset
83 
84 LOCAL	char	*pg_version	__PR((SCSI *scgp, int what));
85 LOCAL	int	pg_help		__PR((SCSI *scgp, FILE *f));
86 LOCAL	int	pg_open		__PR((SCSI *scgp, char *device));
87 LOCAL	int	pg_close	__PR((SCSI *scgp));
88 LOCAL	long	pg_maxdma	__PR((SCSI *scgp, long amt));
89 LOCAL	int 	pg_initiator_id	__PR((SCSI *scgp));
90 LOCAL	int 	pg_isatapi	__PR((SCSI *scgp));
91 LOCAL	int	pg_reset	__PR((SCSI *scgp, int what));
92 LOCAL	int	pg_send		__PR((SCSI *scgp));
93 
94 #endif
95 
96 LOCAL	int	do_scg_cmd	__PR((SCSI *scgp, struct scg_cmd *sp));
97 LOCAL	int	do_scg_sense	__PR((SCSI *scgp, struct scg_cmd *sp));
98 
99 
100 /*
101  * Return version information for the low level SCSI transport code.
102  * This has been introduced to make it easier to trace down problems
103  * in applications.
104  */
105 LOCAL char *
scgo_version(scgp,what)106 scgo_version(scgp, what)
107 	SCSI	*scgp;
108 	int	what;
109 {
110 	if (scgp != (SCSI *)0) {
111 		switch (what) {
112 
113 		case SCG_VERSION:
114 			return (_scg_trans_version_pg);
115 		/*
116 		 * If you changed this source, you are not allowed to
117 		 * return "schily" for the SCG_AUTHOR request.
118 		 */
119 		case SCG_AUTHOR:
120 			return (_scg_auth_schily);
121 		case SCG_SCCS_ID:
122 			return (___sccsid);
123 		}
124 	}
125 	return ((char *)0);
126 }
127 
128 LOCAL int
scgo_help(scgp,f)129 scgo_help(scgp, f)
130 	SCSI	*scgp;
131 	FILE	*f;
132 {
133 	__scg_help(f, "pg", "SCSI transport for ATAPI over Parallel Port",
134 		"", "bus,target,lun", "1,2,0", TRUE, FALSE);
135 	return (0);
136 }
137 
138 LOCAL int
scgo_open(scgp,device)139 scgo_open(scgp, device)
140 	SCSI	*scgp;
141 	char	*device;
142 {
143 		int	busno	= scg_scsibus(scgp);
144 		int	tgt	= scg_target(scgp);
145 		int	tlun	= scg_lun(scgp);
146 	register int	f;
147 	register int	b;
148 #ifdef	USE_PG_ONLY
149 	register int	t;
150 	register int	l;
151 #endif
152 	register int	nopen = 0;
153 	char		devname[32];
154 
155 	if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) {
156 		errno = EINVAL;
157 		if (scgp->errstr)
158 			js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
159 				"Illegal value for busno, target or lun '%d,%d,%d'",
160 				busno, tgt, tlun);
161 		return (-1);
162 	}
163 
164 #ifndef	USE_PG_ONLY
165 	/*
166 	 * We need to find a fake bus number for the parallel port interface.
167 	 * Unfortunatly, the buscookie array may contain holes if
168 	 * SCSI_IOCTL_GET_BUS_NUMBER works, so we are searching backwards
169 	 * for some place for us.
170 	 * XXX Should add extra space in buscookies for a "PP bus".
171 	 */
172 
173 	if (scglocal(scgp)->buscookies[MAX_SCG-1] != (short)-1)
174 		return (0);			/* No space for pgbus */
175 
176 	for (b = MAX_SCG-1; b >= 0; b--) {
177 		if (scglocal(scgp)->buscookies[b] != (short)-1) {
178 			scglocal(scgp)->pgbus = ++b;
179 			break;
180 		}
181 	}
182 	if (scgp->debug > 0) {
183 		js_fprintf((FILE *)scgp->errfile,
184 			"PP Bus: %d\n", scglocal(scgp)->pgbus);
185 	}
186 #else
187 	if (scgp->local == NULL) {
188 		scgp->local = malloc(sizeof (struct scg_local));
189 		if (scgp->local == NULL)
190 			return (0);
191 
192 		scglocal(scgp)->pgbus = -2;
193 		scglocal(scgp)->SCSIbuf = (char *)-1;
194 
195 		for (b = 0; b < MAX_SCG; b++) {
196 			for (t = 0; t < MAX_TGT; t++) {
197 				for (l = 0; l < MAX_LUN; l++)
198 					scglocal(scgp)->scgfiles[b][t][l] = (short)-1;
199 			}
200 		}
201 	}
202 #endif
203 	if (scglocal(scgp)->pgbus < 0)
204 		scglocal(scgp)->pgbus = 0;
205 
206 	if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2))
207 		goto openbydev;
208 
209 	if (busno >= 0 && tgt >= 0 && tlun >= 0) {
210 #ifndef	USE_PG_ONLY
211 		if (scglocal(scgp)->pgbus != busno)
212 			return (0);
213 #endif
214 		js_snprintf(devname, sizeof (devname), "/dev/pg%d", tgt);
215 		f = open(devname, O_RDWR | O_NONBLOCK);
216 		if (f < 0) {
217 			if (scgp->errstr)
218 				js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
219 						"Cannot open '%s'", devname);
220 			return (0);
221 		}
222 		scglocal(scgp)->scgfiles[busno][tgt][tlun] = f;
223 		return (1);
224 	} else {
225 		tlun = 0;
226 		for (tgt = 0; tgt < MAX_TGT; tgt++) {
227 			js_snprintf(devname, sizeof (devname), "/dev/pg%d", tgt);
228 			f = open(devname, O_RDWR | O_NONBLOCK);
229 			if (f < 0) {
230 				/*
231 				 * Set up error string but let us clear it later
232 				 * if at least one open succeeded.
233 				 */
234 				if (scgp->errstr)
235 					js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
236 							"Cannot open '/dev/pg*'");
237 				if (errno != ENOENT && errno != ENXIO && errno != ENODEV) {
238 					if (scgp->errstr)
239 						js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
240 							"Cannot open '%s'", devname);
241 					return (0);
242 				}
243 			} else {
244 				scglocal(scgp)->scgfiles[scglocal(scgp)->pgbus][tgt][tlun] = f;
245 				nopen++;
246 			}
247 		}
248 	}
249 	if (nopen > 0 && scgp->errstr)
250 		scgp->errstr[0] = '\0';
251 
252 openbydev:
253 	if (device != NULL && *device != '\0') {
254 		char	*p;
255 
256 		if (tlun < 0)
257 			return (0);
258 		f = open(device, O_RDWR | O_NONBLOCK);
259 /*		if (f < 0 && errno == ENOENT) {*/
260 		if (f < 0) {
261 			if (scgp->errstr)
262 				js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
263 					"Cannot open '%s'",
264 					device);
265 			return (0);
266 		}
267 
268 		p = device + strlen(device) -1;
269 		tgt = *p - '0';
270 		if (tgt < 0 || tgt > 9)
271 			return (0);
272 		scglocal(scgp)->scgfiles[scglocal(scgp)->pgbus][tgt][tlun] = f;
273 		scg_settarget(scgp, scglocal(scgp)->pgbus, tgt, tlun);
274 
275 		return (++nopen);
276 	}
277 	return (nopen);
278 }
279 
280 LOCAL int
scgo_close(scgp)281 scgo_close(scgp)
282 	SCSI	*scgp;
283 {
284 	register int	f;
285 	register int	b;
286 	register int	t;
287 	register int	l;
288 
289 	if (scgp->local == NULL)
290 		return (-1);
291 	if (scglocal(scgp)->pgbus < 0)
292 		return (0);
293 	b = scglocal(scgp)->pgbus;
294 	scglocal(scgp)->buscookies[b] = (short)-1;
295 
296 	for (t = 0; t < MAX_TGT; t++) {
297 		for (l = 0; l < MAX_LUN; l++) {
298 			f = scglocal(scgp)->scgfiles[b][t][l];
299 			if (f >= 0)
300 				close(f);
301 			scglocal(scgp)->scgfiles[b][t][l] = (short)-1;
302 		}
303 	}
304 	return (0);
305 }
306 
307 LOCAL long
scgo_maxdma(scgp,amt)308 scgo_maxdma(scgp, amt)
309 	SCSI	*scgp;
310 	long	amt;
311 {
312 	return (PG_MAX_DATA);
313 }
314 
315 #ifdef	USE_PG_ONLY
316 
317 LOCAL void *
scgo_getbuf(scgp,amt)318 scgo_getbuf(scgp, amt)
319 	SCSI	*scgp;
320 	long	amt;
321 {
322 	char    *ret;
323 
324 	if (scgp->debug > 0) {
325 		js_fprintf((FILE *)scgp->errfile,
326 			"scgo_getbuf: %ld bytes\n", amt);
327 	}
328 	ret = valloc((size_t)(amt+getpagesize()));
329 	if (ret == NULL)
330 		return (ret);
331 	scgp->bufbase = ret;
332 	ret += getpagesize();
333 	scglocal(scgp)->SCSIbuf = ret;
334 	return ((void *)ret);
335 
336 }
337 
338 LOCAL void
scgo_freebuf(scgp)339 scgo_freebuf(scgp)
340 	SCSI	*scgp;
341 {
342 	if (scgp->bufbase)
343 		free(scgp->bufbase);
344 	scgp->bufbase = NULL;
345 }
346 
347 LOCAL int
scgo_numbus(scgp)348 scgo_numbus(scgp)
349 	SCSI	*scgp;
350 {
351 	return (MAX_SCG);
352 }
353 
354 LOCAL BOOL
scgo_havebus(scgp,busno)355 scgo_havebus(scgp, busno)
356 	SCSI	*scgp;
357 	int	busno;
358 {
359 	register int	t;
360 	register int	l;
361 
362 	if (busno < 0 || busno >= MAX_SCG)
363 		return (FALSE);
364 
365 	if (scgp->local == NULL)
366 		return (FALSE);
367 
368 	for (t = 0; t < MAX_TGT; t++) {
369 		for (l = 0; l < MAX_LUN; l++)
370 			if (scglocal(scgp)->scgfiles[busno][t][l] >= 0)
371 				return (TRUE);
372 	}
373 	return (FALSE);
374 }
375 
376 LOCAL int
scgo_fileno(scgp,busno,tgt,tlun)377 scgo_fileno(scgp, busno, tgt, tlun)
378 	SCSI	*scgp;
379 	int	busno;
380 	int	tgt;
381 	int	tlun;
382 {
383 	if (busno < 0 || busno >= MAX_SCG ||
384 	    tgt < 0 || tgt >= MAX_TGT ||
385 	    tlun < 0 || tlun >= MAX_LUN)
386 		return (-1);
387 
388 	if (scgp->local == NULL)
389 		return (-1);
390 
391 	return ((int)scglocal(scgp)->scgfiles[busno][tgt][tlun]);
392 }
393 #endif	/* USE_PG_ONLY */
394 
395 LOCAL int
scgo_initiator_id(scgp)396 scgo_initiator_id(scgp)
397 	SCSI	*scgp;
398 {
399 	return (-1);
400 }
401 
402 LOCAL int
scgo_isatapi(scgp)403 scgo_isatapi(scgp)
404 	SCSI	*scgp;
405 {
406 	return (TRUE);
407 }
408 
409 LOCAL int
scgo_reset(scgp,what)410 scgo_reset(scgp, what)
411 	SCSI	*scgp;
412 	int	what;
413 {
414 	struct pg_write_hdr hdr = {PG_MAGIC, PG_RESET, 0};
415 
416 	if (what == SCG_RESET_NOP)
417 		return (0);
418 	if (what != SCG_RESET_BUS) {
419 		errno = EINVAL;
420 		return (-1);
421 	}
422 	/*
423 	 * XXX Does this reset TGT or BUS ???
424 	 */
425 	return (write(scgp->fd, (char *)&hdr, sizeof (hdr)));
426 
427 }
428 
429 #ifndef MAX
430 #define	MAX(a, b)	((a) > (b) ? (a):(b))
431 #endif
432 
433 #define	RHSIZE	sizeof (struct pg_read_hdr)
434 #define	WHSIZE  sizeof (struct pg_write_hdr)
435 #define	LEAD	MAX(RHSIZE, WHSIZE)
436 
437 LOCAL int
do_scg_cmd(scgp,sp)438 do_scg_cmd(scgp, sp)
439 	SCSI	*scgp;
440 	struct scg_cmd	*sp;
441 {
442 
443 	char	local[LEAD+PG_MAX_DATA];
444 	int	use_local, i, r;
445 	int	inward = (sp->flags & SCG_RECV_DATA);
446 
447 	struct pg_write_hdr *whp;
448 	struct pg_read_hdr  *rhp;
449 	char		    *dbp;
450 
451 	if (sp->cdb_len > 12)
452 		comerrno(EX_BAD, "Can't do %d byte command.\n", sp->cdb_len);
453 
454 	if (sp->addr == scglocal(scgp)->SCSIbuf) {
455 		use_local = 0;
456 		dbp = sp->addr;
457 	} else {
458 		use_local = 1;
459 		dbp = &local[LEAD];
460 		if (!inward)
461 			movebytes(sp->addr, dbp, sp->size);
462 	}
463 
464 	whp = (struct pg_write_hdr *)(dbp - WHSIZE);
465 	rhp = (struct pg_read_hdr *)(dbp - RHSIZE);
466 
467 	whp->magic   = PG_MAGIC;
468 	whp->func    = PG_COMMAND;
469 	whp->dlen    = sp->size;
470 	whp->timeout = sp->timeout;
471 
472 	for (i = 0; i < 12; i++) {
473 		if (i < sp->cdb_len)
474 			whp->packet[i] = sp->cdb.cmd_cdb[i];
475 		else
476 			whp->packet[i] = 0;
477 	}
478 
479 	i = WHSIZE;
480 	if (!inward)
481 		i += sp->size;
482 
483 	r = write(scgp->fd, (char *)whp, i);
484 
485 	if (r < 0) {				/* command was not sent */
486 		sp->ux_errno = geterrno();
487 		if (sp->ux_errno == ETIME) {
488 			/*
489 			 * If the previous command timed out, we cannot send
490 			 * any further command until the command in the drive
491 			 * is ready. So we behave as if the drive did not
492 			 * respond to the command.
493 			 */
494 			sp->error = SCG_FATAL;
495 			return (0);
496 		}
497 		return (-1);
498 	}
499 
500 	if (r != i)
501 		errmsg("scgo_send(%s) wrote %d bytes (expected %d).\n",
502 			scgp->cmdname, r, i);
503 
504 	sp->ux_errno = 0;
505 	sp->sense_count = 0;
506 
507 	r = read(scgp->fd, (char *)rhp, RHSIZE+sp->size);
508 
509 	if (r < 0) {
510 		sp->ux_errno = geterrno();
511 		if (sp->ux_errno == ETIME) {
512 			sp->error = SCG_TIMEOUT;
513 			return (0);
514 		}
515 		sp->error = SCG_FATAL;
516 		return (-1);
517 	}
518 
519 	i = rhp->dlen;
520 	if (i > sp->size) {
521 		/*
522 		 * "DMA overrun" should be handled in the kernel.
523 		 * However this may happen with flaky PP adapters.
524 		 */
525 		errmsgno(EX_BAD,
526 			"DMA (read) overrun by %d bytes (requested %d bytes).\n",
527 			i - sp->size, sp->size);
528 		sp->resid = sp->size - i;
529 		sp->error = SCG_RETRYABLE;
530 		i = sp->size;
531 	} else {
532 		sp->resid = sp->size - i;
533 	}
534 
535 	if (use_local && inward)
536 		movebytes(dbp, sp->addr, i);
537 
538 	fillbytes(&sp->scb, sizeof (sp->scb), '\0');
539 	fillbytes(&sp->u_sense.cmd_sense, sizeof (sp->u_sense.cmd_sense), '\0');
540 
541 	sp->error = SCG_NO_ERROR;
542 	i = rhp->scsi?2:0;
543 /*	i = rhp->scsi;*/
544 	sp->u_scb.cmd_scb[0] = i;
545 	if (i & 2) {
546 		if (sp->ux_errno == 0)
547 			sp->ux_errno = EIO;
548 		/*
549 		 * If there is no DMA overrun and there is a
550 		 * SCSI Status byte != 0 then the SCSI cdb transport was OK
551 		 * and sp->error must be SCG_NO_ERROR.
552 		 */
553 /*		sp->error = SCG_RETRYABLE;*/
554 	}
555 
556 	return (0);
557 
558 }
559 
560 LOCAL int
do_scg_sense(scgp,sp)561 do_scg_sense(scgp, sp)
562 	SCSI	*scgp;
563 	struct scg_cmd	*sp;
564 {
565 	int		ret;
566 	struct scg_cmd 	s_cmd;
567 
568 	fillbytes((caddr_t)&s_cmd, sizeof (s_cmd), '\0');
569 	s_cmd.addr = (caddr_t)sp->u_sense.cmd_sense;
570 	s_cmd.size = sp->sense_len;
571 	s_cmd.flags = SCG_RECV_DATA|SCG_DISRE_ENA;
572 	s_cmd.cdb_len = SC_G0_CDBLEN;
573 	s_cmd.sense_len = CCS_SENSE_LEN;
574 	s_cmd.cdb.g0_cdb.cmd = SC_REQUEST_SENSE;
575 	s_cmd.cdb.g0_cdb.lun = sp->cdb.g0_cdb.lun;
576 	s_cmd.cdb.g0_cdb.count = sp->sense_len;
577 	ret = do_scg_cmd(scgp, &s_cmd);
578 
579 	if (ret < 0)
580 		return (ret);
581 
582 	sp->sense_count = sp->sense_len - s_cmd.resid;
583 	return (ret);
584 }
585 
586 LOCAL int
scgo_send(scgp)587 scgo_send(scgp)
588 	SCSI		*scgp;
589 {
590 	struct scg_cmd	*sp = scgp->scmd;
591 	int	error = sp->error;
592 	Uchar	status = sp->u_scb.cmd_scb[0];
593 	int	ret;
594 
595 	if (scgp->fd < 0) {
596 		sp->error = SCG_FATAL;
597 		return (0);
598 	}
599 	ret = do_scg_cmd(scgp, sp);
600 	if (ret >= 0) {
601 		if (sp->u_scb.cmd_scb[0] & 02)
602 			ret = do_scg_sense(scgp, sp);
603 	}
604 	sp->error = error;
605 	sp->u_scb.cmd_scb[0] = status;
606 	return (ret);
607 }
608 
609 /* end of scsi-linux-pg.c */
610 
611 #ifndef	USE_PG_ONLY
612 
613 #undef	scgo_version
614 #undef	scgo_help
615 #undef	scgo_open
616 #undef	scgo_close
617 #undef	scgo_send
618 #undef	scgo_maxdma
619 #undef	scgo_initiator_id
620 #undef	scgo_isatapi
621 #undef	scgo_reset
622 
623 #endif
624