1 /*
2  * acsi_slm.c -- Device driver for the Atari SLM laser printer
3  *
4  * Copyright 1995 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file COPYING in the main directory of this archive for
8  * more details.
9  *
10  */
11 
12 /*
13 
14 Notes:
15 
16 The major number for SLM printers is 28 (like ACSI), but as a character
17 device, not block device. The minor number is the number of the printer (if
18 you have more than one SLM; currently max. 2 (#define-constant) SLMs are
19 supported). The device can be opened for reading and writing. If reading it,
20 you get some status infos (MODE SENSE data). Writing mode is used for the data
21 to be printed. Some ioctls allow to get the printer status and to tune printer
22 modes and some internal variables.
23 
24 A special problem of the SLM driver is the timing and thus the buffering of
25 the print data. The problem is that all the data for one page must be present
26 in memory when printing starts, else --when swapping occurs-- the timing could
27 not be guaranteed. There are several ways to assure this:
28 
29  1) Reserve a buffer of 1196k (maximum page size) statically by
30     atari_stram_alloc(). The data are collected there until they're complete,
31 	and then printing starts. Since the buffer is reserved, no further
32 	considerations about memory and swapping are needed. So this is the
33 	simplest method, but it needs a lot of memory for just the SLM.
34 
35     An striking advantage of this method is (supposed the SLM_CONT_CNT_REPROG
36 	method works, see there), that there are no timing problems with the DMA
37 	anymore.
38 
39  2) The other method would be to reserve the buffer dynamically each time
40     printing is required. I could think of looking at mem_map where the
41 	largest unallocted ST-RAM area is, taking the area, and then extending it
42 	by swapping out the neighbored pages, until the needed size is reached.
43 	This requires some mm hacking, but seems possible. The only obstacle could
44 	be pages that cannot be swapped out (reserved pages)...
45 
46  3) Another possibility would be to leave the real data in user space and to
47     work with two dribble buffers of about 32k in the driver: While the one
48 	buffer is DMAed to the SLM, the other can be filled with new data. But
49 	to keep the timing, that requires that the user data remain in memory and
50 	are not swapped out. Requires mm hacking, too, but maybe not so bad as
51 	method 2).
52 
53 */
54 
55 #include <linux/module.h>
56 
57 #include <linux/errno.h>
58 #include <linux/sched.h>
59 #include <linux/timer.h>
60 #include <linux/fs.h>
61 #include <linux/major.h>
62 #include <linux/kernel.h>
63 #include <linux/delay.h>
64 #include <linux/interrupt.h>
65 #include <linux/time.h>
66 #include <linux/mm.h>
67 #include <linux/slab.h>
68 #include <linux/devfs_fs_kernel.h>
69 #include <linux/smp_lock.h>
70 
71 #include <asm/pgtable.h>
72 #include <asm/system.h>
73 #include <asm/uaccess.h>
74 #include <asm/atarihw.h>
75 #include <asm/atariints.h>
76 #include <asm/atari_acsi.h>
77 #include <asm/atari_stdma.h>
78 #include <asm/atari_stram.h>
79 #include <asm/atari_SLM.h>
80 
81 
82 #undef	DEBUG
83 
84 /* Define this if the page data are continuous in physical memory. That
85  * requires less reprogramming of the ST-DMA */
86 #define	SLM_CONTINUOUS_DMA
87 
88 /* Use continuous reprogramming of the ST-DMA counter register. This is
89  * --strictly speaking-- not allowed, Atari recommends not to look at the
90  * counter register while a DMA is going on. But I don't know if that applies
91  * only for reading the register, or also writing to it. Writing only works
92  * fine for me... The advantage is that the timing becomes absolutely
93  * uncritical: Just update each, say 200ms, the counter reg to its maximum,
94  * and the DMA will work until the status byte interrupt occurs.
95  */
96 #define	SLM_CONT_CNT_REPROG
97 
98 #define MAJOR_NR ACSI_MAJOR
99 
100 #define CMDSET_TARG_LUN(cmd,targ,lun)			\
101     do {										\
102 		cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5;	\
103 		cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5;	\
104 	} while(0)
105 
106 #define	START_TIMER(to)	mod_timer(&slm_timer, jiffies + (to))
107 #define	STOP_TIMER()	del_timer(&slm_timer)
108 
109 
110 static char slmreqsense_cmd[6] = { 0x03, 0, 0, 0, 0, 0 };
111 static char slmprint_cmd[6]    = { 0x0a, 0, 0, 0, 0, 0 };
112 static char slminquiry_cmd[6]  = { 0x12, 0, 0, 0, 0, 0x80 };
113 static char slmmsense_cmd[6]   = { 0x1a, 0, 0, 0, 255, 0 };
114 #if 0
115 static char slmmselect_cmd[6]  = { 0x15, 0, 0, 0, 0, 0 };
116 #endif
117 
118 
119 #define	MAX_SLM		2
120 
121 static struct slm {
122 	unsigned	target;			/* target number */
123 	unsigned	lun;			/* LUN in target controller */
124 	unsigned	wbusy : 1;		/* output part busy */
125 	unsigned	rbusy : 1;		/* status part busy */
126 } slm_info[MAX_SLM];
127 
128 int N_SLM_Printers = 0;
129 
130 /* printer buffer */
131 static unsigned char	*SLMBuffer;	/* start of buffer */
132 static unsigned char	*BufferP;	/* current position in buffer */
133 static int				BufferSize;	/* length of buffer for page size */
134 
135 typedef enum { IDLE, FILLING, PRINTING } SLMSTATE;
136 static SLMSTATE			SLMState;
137 static int				SLMBufOwner;	/* SLM# currently using the buffer */
138 
139 /* DMA variables */
140 #ifndef SLM_CONT_CNT_REPROG
141 static unsigned long	SLMCurAddr;		/* current base addr of DMA chunk */
142 static unsigned long	SLMEndAddr;		/* expected end addr */
143 static unsigned long	SLMSliceSize;	/* size of one DMA chunk */
144 #endif
145 static int				SLMError;
146 
147 /* wait queues */
148 static DECLARE_WAIT_QUEUE_HEAD(slm_wait);	/* waiting for buffer */
149 static DECLARE_WAIT_QUEUE_HEAD(print_wait);	/* waiting for printing finished */
150 
151 /* status codes */
152 #define	SLMSTAT_OK		0x00
153 #define	SLMSTAT_ORNERY	0x02
154 #define	SLMSTAT_TONER	0x03
155 #define	SLMSTAT_WARMUP	0x04
156 #define	SLMSTAT_PAPER	0x05
157 #define	SLMSTAT_DRUM	0x06
158 #define	SLMSTAT_INJAM	0x07
159 #define	SLMSTAT_THRJAM	0x08
160 #define	SLMSTAT_OUTJAM	0x09
161 #define	SLMSTAT_COVER	0x0a
162 #define	SLMSTAT_FUSER	0x0b
163 #define	SLMSTAT_IMAGER	0x0c
164 #define	SLMSTAT_MOTOR	0x0d
165 #define	SLMSTAT_VIDEO	0x0e
166 #define	SLMSTAT_SYSTO	0x10
167 #define	SLMSTAT_OPCODE	0x12
168 #define	SLMSTAT_DEVNUM	0x15
169 #define	SLMSTAT_PARAM	0x1a
170 #define	SLMSTAT_ACSITO	0x1b	/* driver defined */
171 #define	SLMSTAT_NOTALL	0x1c	/* driver defined */
172 
173 static char *SLMErrors[] = {
174 	/* 0x00 */	"OK and ready",
175 	/* 0x01 */	NULL,
176 	/* 0x02 */	"ornery printer",
177 	/* 0x03 */	"toner empty",
178 	/* 0x04 */	"warming up",
179 	/* 0x05 */	"paper empty",
180 	/* 0x06 */	"drum empty",
181 	/* 0x07 */	"input jam",
182 	/* 0x08 */	"through jam",
183 	/* 0x09 */	"output jam",
184 	/* 0x0a */	"cover open",
185 	/* 0x0b */	"fuser malfunction",
186 	/* 0x0c */	"imager malfunction",
187 	/* 0x0d */	"motor malfunction",
188 	/* 0x0e */	"video malfunction",
189 	/* 0x0f */	NULL,
190 	/* 0x10 */	"printer system timeout",
191 	/* 0x11 */	NULL,
192 	/* 0x12 */	"invalid operation code",
193 	/* 0x13 */	NULL,
194 	/* 0x14 */	NULL,
195 	/* 0x15 */	"invalid device number",
196 	/* 0x16 */	NULL,
197 	/* 0x17 */	NULL,
198 	/* 0x18 */	NULL,
199 	/* 0x19 */	NULL,
200 	/* 0x1a */	"invalid parameter list",
201 	/* 0x1b */	"ACSI timeout",
202 	/* 0x1c */	"not all printed"
203 };
204 
205 #define	N_ERRORS	(sizeof(SLMErrors)/sizeof(*SLMErrors))
206 
207 /* real (driver caused) error? */
208 #define	IS_REAL_ERROR(x)	(x > 0x10)
209 
210 
211 static struct {
212 	char	*name;
213 	int 	w, h;
214 } StdPageSize[] = {
215 	{ "Letter", 2400, 3180 },
216 	{ "Legal",  2400, 4080 },
217 	{ "A4",     2336, 3386 },
218 	{ "B5",     2016, 2914 }
219 };
220 
221 #define	N_STD_SIZES		(sizeof(StdPageSize)/sizeof(*StdPageSize))
222 
223 #define	SLM_BUFFER_SIZE	(2336*3386/8)	/* A4 for now */
224 #define	SLM_DMA_AMOUNT	255				/* #sectors to program the DMA for */
225 
226 #ifdef	SLM_CONTINUOUS_DMA
227 # define	SLM_DMA_INT_OFFSET	0		/* DMA goes until seccnt 0, no offs */
228 # define	SLM_DMA_END_OFFSET	32		/* 32 Byte ST-DMA FIFO */
229 # define	SLM_SLICE_SIZE(w) 	(255*512)
230 #else
231 # define	SLM_DMA_INT_OFFSET	32		/* 32 Byte ST-DMA FIFO */
232 # define	SLM_DMA_END_OFFSET	32		/* 32 Byte ST-DMA FIFO */
233 # define	SLM_SLICE_SIZE(w)	((254*512)/(w/8)*(w/8))
234 #endif
235 
236 /* calculate the number of jiffies to wait for 'n' bytes */
237 #ifdef SLM_CONT_CNT_REPROG
238 #define	DMA_TIME_FOR(n)		50
239 #define	DMA_STARTUP_TIME	0
240 #else
241 #define	DMA_TIME_FOR(n)		(n/1400-1)
242 #define	DMA_STARTUP_TIME	650
243 #endif
244 
245 /***************************** Prototypes *****************************/
246 
247 static char *slm_errstr( int stat );
248 static int slm_getstats( char *buffer, int device );
249 static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t
250                          *ppos );
251 static void start_print( int device );
252 static void slm_interrupt(int irc, void *data, struct pt_regs *fp);
253 static void slm_test_ready( unsigned long dummy );
254 static void set_dma_addr( unsigned long paddr );
255 static unsigned long get_dma_addr( void );
256 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
257                           loff_t *ppos );
258 static int slm_ioctl( struct inode *inode, struct file *file, unsigned int
259                       cmd, unsigned long arg );
260 static int slm_open( struct inode *inode, struct file *file );
261 static int slm_release( struct inode *inode, struct file *file );
262 static int slm_req_sense( int device );
263 static int slm_mode_sense( int device, char *buffer, int abs_flag );
264 #if 0
265 static int slm_mode_select( int device, char *buffer, int len, int
266                             default_flag );
267 #endif
268 static int slm_get_pagesize( int device, int *w, int *h );
269 
270 /************************* End of Prototypes **************************/
271 
272 
273 static struct timer_list slm_timer = { function: slm_test_ready };
274 
275 static struct file_operations slm_fops = {
276 	owner:		THIS_MODULE,
277 	read:		slm_read,
278 	write:		slm_write,
279 	ioctl:		slm_ioctl,
280 	open:		slm_open,
281 	release:	slm_release,
282 };
283 
284 
285 /* ---------------------------------------------------------------------- */
286 /*							   Status Functions							  */
287 
288 
slm_errstr(int stat)289 static char *slm_errstr( int stat )
290 
291 {	char *p;
292 	static char	str[22];
293 
294 	stat &= 0x1f;
295 	if (stat >= 0 && stat < N_ERRORS && (p = SLMErrors[stat]))
296 		return( p );
297 	sprintf( str, "unknown status 0x%02x", stat );
298 	return( str );
299 }
300 
301 
slm_getstats(char * buffer,int device)302 static int slm_getstats( char *buffer, int device )
303 
304 {	int 			len = 0, stat, i, w, h;
305 	unsigned char	buf[256];
306 
307 	stat = slm_mode_sense( device, buf, 0 );
308 	if (IS_REAL_ERROR(stat))
309 		return( -EIO );
310 
311 #define SHORTDATA(i)		((buf[i] << 8) | buf[i+1])
312 #define	BOOLDATA(i,mask)	((buf[i] & mask) ? "on" : "off")
313 
314 	w = SHORTDATA( 3 );
315 	h = SHORTDATA( 1 );
316 
317 	len += sprintf( buffer+len, "Status\t\t%s\n",
318 					slm_errstr( stat ) );
319 	len += sprintf( buffer+len, "Page Size\t%dx%d",
320 					w, h );
321 
322 	for( i = 0; i < N_STD_SIZES; ++i ) {
323 		if (w == StdPageSize[i].w && h == StdPageSize[i].h)
324 			break;
325 	}
326 	if (i < N_STD_SIZES)
327 		len += sprintf( buffer+len, " (%s)", StdPageSize[i].name );
328 	buffer[len++] = '\n';
329 
330 	len += sprintf( buffer+len, "Top/Left Margin\t%d/%d\n",
331 					SHORTDATA( 5 ), SHORTDATA( 7 ) );
332 	len += sprintf( buffer+len, "Manual Feed\t%s\n",
333 					BOOLDATA( 9, 0x01 ) );
334 	len += sprintf( buffer+len, "Input Select\t%d\n",
335 					(buf[9] >> 1) & 7 );
336 	len += sprintf( buffer+len, "Auto Select\t%s\n",
337 					BOOLDATA( 9, 0x10 ) );
338 	len += sprintf( buffer+len, "Prefeed Paper\t%s\n",
339 					BOOLDATA( 9, 0x20 ) );
340 	len += sprintf( buffer+len, "Thick Pixels\t%s\n",
341 					BOOLDATA( 9, 0x40 ) );
342 	len += sprintf( buffer+len, "H/V Resol.\t%d/%d dpi\n",
343 					SHORTDATA( 12 ), SHORTDATA( 10 ) );
344 	len += sprintf( buffer+len, "System Timeout\t%d\n",
345 					buf[14] );
346 	len += sprintf( buffer+len, "Scan Time\t%d\n",
347 					SHORTDATA( 15 ) );
348 	len += sprintf( buffer+len, "Page Count\t%d\n",
349 					SHORTDATA( 17 ) );
350 	len += sprintf( buffer+len, "In/Out Cap.\t%d/%d\n",
351 					SHORTDATA( 19 ), SHORTDATA( 21 ) );
352 	len += sprintf( buffer+len, "Stagger Output\t%s\n",
353 					BOOLDATA( 23, 0x01 ) );
354 	len += sprintf( buffer+len, "Output Select\t%d\n",
355 					(buf[23] >> 1) & 7 );
356 	len += sprintf( buffer+len, "Duplex Print\t%s\n",
357 					BOOLDATA( 23, 0x10 ) );
358 	len += sprintf( buffer+len, "Color Sep.\t%s\n",
359 					BOOLDATA( 23, 0x20 ) );
360 
361 	return( len );
362 }
363 
364 
slm_read(struct file * file,char * buf,size_t count,loff_t * ppos)365 static ssize_t slm_read( struct file *file, char *buf, size_t count,
366 						 loff_t *ppos )
367 
368 {
369 	struct inode *node = file->f_dentry->d_inode;
370 	loff_t pos = *ppos;
371 	unsigned long page;
372 	int length;
373 	int end;
374 
375 	if (count < 0)
376 		return( -EINVAL );
377 	if (!(page = __get_free_page( GFP_KERNEL )))
378 		return( -ENOMEM );
379 
380 	length = slm_getstats( (char *)page, MINOR(node->i_rdev) );
381 	if (length < 0) {
382 		count = length;
383 		goto out;
384 	}
385 	if (pos != (unsigned) pos || pos >= length) {
386 		count = 0;
387 		goto out;
388 	}
389 	if (count > length - pos)
390 		count = length - pos;
391 	end = count + pos;
392 	if (copy_to_user(buf, (char *)page + pos, count)) {
393 		count = -EFAULT;
394 		goto out;
395 	}
396 	*ppos = end;
397 out:	free_page( page );
398 	return( count );
399 }
400 
401 
402 /* ---------------------------------------------------------------------- */
403 /*								   Printing								  */
404 
405 
start_print(int device)406 static void start_print( int device )
407 
408 {	struct slm *sip = &slm_info[device];
409 	unsigned char	*cmd;
410 	unsigned long	paddr;
411 	int				i;
412 
413 	stdma_lock( slm_interrupt, NULL );
414 
415 	CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun );
416 	cmd = slmprint_cmd;
417 	paddr = virt_to_phys( SLMBuffer );
418 	dma_cache_maintenance( paddr, virt_to_phys(BufferP)-paddr, 1 );
419 	DISABLE_IRQ();
420 
421 	/* Low on A1 */
422 	dma_wd.dma_mode_status = 0x88;
423 	MFPDELAY();
424 
425 	/* send the command bytes except the last */
426 	for( i = 0; i < 5; ++i ) {
427 		DMA_LONG_WRITE( *cmd++, 0x8a );
428 		udelay(20);
429 		if (!acsi_wait_for_IRQ( HZ/2 )) {
430 			SLMError = 1;
431 			return; /* timeout */
432 		}
433 	}
434 	/* last command byte */
435 	DMA_LONG_WRITE( *cmd++, 0x82 );
436 	MFPDELAY();
437 	/* set DMA address */
438 	set_dma_addr( paddr );
439 	/* program DMA for write and select sector counter reg */
440 	dma_wd.dma_mode_status = 0x192;
441 	MFPDELAY();
442 	/* program for 255*512 bytes and start DMA */
443 	DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
444 
445 #ifndef SLM_CONT_CNT_REPROG
446 	SLMCurAddr = paddr;
447 	SLMEndAddr = paddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
448 #endif
449 	START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize ));
450 #if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG)
451 	printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
452 			SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
453 #endif
454 
455 	ENABLE_IRQ();
456 }
457 
458 
459 /* Only called when an error happened or at the end of a page */
460 
slm_interrupt(int irc,void * data,struct pt_regs * fp)461 static void slm_interrupt(int irc, void *data, struct pt_regs *fp)
462 
463 {	unsigned long	addr;
464 	int				stat;
465 
466 	STOP_TIMER();
467 	addr = get_dma_addr();
468 	stat = acsi_getstatus();
469 	SLMError = (stat < 0)             ? SLMSTAT_ACSITO :
470 		       (addr < virt_to_phys(BufferP)) ? SLMSTAT_NOTALL :
471 									    stat;
472 
473 	dma_wd.dma_mode_status = 0x80;
474 	MFPDELAY();
475 #ifdef DEBUG
476 	printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr, SLMError );
477 #endif
478 
479 	wake_up( &print_wait );
480 	stdma_release();
481 	ENABLE_IRQ();
482 }
483 
484 
slm_test_ready(unsigned long dummy)485 static void slm_test_ready( unsigned long dummy )
486 
487 {
488 #ifdef SLM_CONT_CNT_REPROG
489 	/* program for 255*512 bytes again */
490 	dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
491 	START_TIMER( DMA_TIME_FOR(0) );
492 #ifdef DEBUG
493 	printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
494 			DMA_TIME_FOR(0), get_dma_addr() );
495 #endif
496 
497 #else /* !SLM_CONT_CNT_REPROG */
498 
499 	unsigned long	flags, addr;
500 	int				d, ti;
501 #ifdef DEBUG
502 	struct timeval start_tm, end_tm;
503 	int			   did_wait = 0;
504 #endif
505 
506 	save_flags(flags);
507 	cli();
508 
509 	addr = get_dma_addr();
510 	if ((d = SLMEndAddr - addr) > 0) {
511 		restore_flags(flags);
512 
513 		/* slice not yet finished, decide whether to start another timer or to
514 		 * busy-wait */
515 		ti = DMA_TIME_FOR( d );
516 		if (ti > 0) {
517 #ifdef DEBUG
518 			printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
519 					ti, d );
520 #endif
521 			START_TIMER( ti );
522 			return;
523 		}
524 		/* wait for desired end address to be reached */
525 #ifdef DEBUG
526 		do_gettimeofday( &start_tm );
527 		did_wait = 1;
528 #endif
529 		cli();
530 		while( get_dma_addr() < SLMEndAddr )
531 			barrier();
532 	}
533 
534 	/* slice finished, start next one */
535 	SLMCurAddr += SLMSliceSize;
536 
537 #ifdef SLM_CONTINUOUS_DMA
538 	/* program for 255*512 bytes again */
539 	dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
540 #else
541 	/* set DMA address;
542 	 * add 2 bytes for the ones in the SLM controller FIFO! */
543 	set_dma_addr( SLMCurAddr + 2 );
544 	/* toggle DMA to write and select sector counter reg */
545 	dma_wd.dma_mode_status = 0x92;
546 	MFPDELAY();
547 	dma_wd.dma_mode_status = 0x192;
548 	MFPDELAY();
549 	/* program for 255*512 bytes and start DMA */
550 	DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
551 #endif
552 
553 	restore_flags(flags);
554 
555 #ifdef DEBUG
556 	if (did_wait) {
557 		int ms;
558 		do_gettimeofday( &end_tm );
559 		ms = (end_tm.tv_sec*1000000+end_tm.tv_usec) -
560 			 (start_tm.tv_sec*1000000+start_tm.tv_usec);
561 		printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n",
562 				ms/1000, ms%1000, d );
563 	}
564 	else
565 		printk( "SLM: didn't wait (!)\n" );
566 #endif
567 
568 	if ((unsigned char *)PTOV( SLMCurAddr + SLMSliceSize ) >= BufferP) {
569 		/* will be last slice, no timer necessary */
570 #ifdef DEBUG
571 		printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
572 				SLMCurAddr, SLMEndAddr );
573 #endif
574 	}
575 	else {
576 		/* not last slice */
577 		SLMEndAddr = SLMCurAddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
578 		START_TIMER( DMA_TIME_FOR( SLMSliceSize ));
579 #ifdef DEBUG
580 		printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
581 				SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
582 #endif
583 	}
584 #endif /* SLM_CONT_CNT_REPROG */
585 }
586 
587 
set_dma_addr(unsigned long paddr)588 static void set_dma_addr( unsigned long paddr )
589 
590 {	unsigned long	flags;
591 
592 	save_flags(flags);
593 	cli();
594 	dma_wd.dma_lo = (unsigned char)paddr;
595 	paddr >>= 8;
596 	MFPDELAY();
597 	dma_wd.dma_md = (unsigned char)paddr;
598 	paddr >>= 8;
599 	MFPDELAY();
600 	if (ATARIHW_PRESENT( EXTD_DMA ))
601 		st_dma_ext_dmahi = (unsigned short)paddr;
602 	else
603 		dma_wd.dma_hi = (unsigned char)paddr;
604 	MFPDELAY();
605 	restore_flags(flags);
606 }
607 
608 
get_dma_addr(void)609 static unsigned long get_dma_addr( void )
610 
611 {	unsigned long	addr;
612 
613 	addr = dma_wd.dma_lo & 0xff;
614 	MFPDELAY();
615 	addr |= (dma_wd.dma_md & 0xff) << 8;
616 	MFPDELAY();
617 	addr |= (dma_wd.dma_hi & 0xff) << 16;
618 	MFPDELAY();
619 
620 	return( addr );
621 }
622 
623 
slm_write(struct file * file,const char * buf,size_t count,loff_t * ppos)624 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
625 						  loff_t *ppos )
626 
627 {
628 	struct inode *node = file->f_dentry->d_inode;
629 	int		device = MINOR( node->i_rdev );
630 	int		n, filled, w, h;
631 
632 	while( SLMState == PRINTING ||
633 		   (SLMState == FILLING && SLMBufOwner != device) ) {
634 		interruptible_sleep_on( &slm_wait );
635 		if (signal_pending(current))
636 			return( -ERESTARTSYS );
637 	}
638 	if (SLMState == IDLE) {
639 		/* first data of page: get current page size  */
640 		if (slm_get_pagesize( device, &w, &h ))
641 			return( -EIO );
642 		BufferSize = w*h/8;
643 		if (BufferSize > SLM_BUFFER_SIZE)
644 			return( -ENOMEM );
645 
646 		SLMState = FILLING;
647 		SLMBufOwner = device;
648 	}
649 
650 	n = count;
651 	filled = BufferP - SLMBuffer;
652 	if (filled + n > BufferSize)
653 		n = BufferSize - filled;
654 
655 	if (copy_from_user(BufferP, buf, n))
656 		return -EFAULT;
657 	BufferP += n;
658 	filled += n;
659 
660 	if (filled == BufferSize) {
661 		/* Check the paper size again! The user may have switched it in the
662 		 * time between starting the data and finishing them. Would end up in
663 		 * a trashy page... */
664 		if (slm_get_pagesize( device, &w, &h ))
665 			return( -EIO );
666 		if (BufferSize != w*h/8) {
667 			printk( KERN_NOTICE "slm%d: page size changed while printing\n",
668 					device );
669 			return( -EAGAIN );
670 		}
671 
672 		SLMState = PRINTING;
673 		/* choose a slice size that is a multiple of the line size */
674 #ifndef SLM_CONT_CNT_REPROG
675 		SLMSliceSize = SLM_SLICE_SIZE(w);
676 #endif
677 
678 		start_print( device );
679 		sleep_on( &print_wait );
680 		if (SLMError && IS_REAL_ERROR(SLMError)) {
681 			printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) );
682 			n = -EIO;
683 		}
684 
685 		SLMState = IDLE;
686 		BufferP = SLMBuffer;
687 		wake_up_interruptible( &slm_wait );
688 	}
689 
690 	return( n );
691 }
692 
693 
694 /* ---------------------------------------------------------------------- */
695 /*							   ioctl Functions							  */
696 
697 
slm_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)698 static int slm_ioctl( struct inode *inode, struct file *file,
699 					  unsigned int cmd, unsigned long arg )
700 
701 {	int		device = MINOR( inode->i_rdev ), err;
702 
703 	/* I can think of setting:
704 	 *  - manual feed
705 	 *  - paper format
706 	 *  - copy count
707 	 *  - ...
708 	 * but haven't implemented that yet :-)
709 	 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
710 	 */
711 	switch( cmd ) {
712 
713 	  case SLMIORESET:		/* reset buffer, i.e. empty the buffer */
714 		if (!(file->f_mode & 2))
715 			return( -EINVAL );
716 		if (SLMState == PRINTING)
717 			return( -EBUSY );
718 		SLMState = IDLE;
719 		BufferP = SLMBuffer;
720 		wake_up_interruptible( &slm_wait );
721 		return( 0 );
722 
723 	  case SLMIOGSTAT: {	/* get status */
724 		int stat;
725 		char *str;
726 
727 		stat = slm_req_sense( device );
728 		if (arg) {
729 			str = slm_errstr( stat );
730 			if (put_user(stat,
731     	    	    	    	     (long *)&((struct SLM_status *)arg)->stat))
732     	    	    	    	return -EFAULT;
733 			if (copy_to_user( ((struct SLM_status *)arg)->str, str,
734 						 strlen(str) + 1))
735 				return -EFAULT;
736 		}
737 		return( stat );
738 	  }
739 
740 	  case SLMIOGPSIZE: {	/* get paper size */
741 		int w, h;
742 
743 		if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
744 
745     	    	if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
746 			return -EFAULT;
747 		if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height))
748 			return -EFAULT;
749 		return( 0 );
750 	  }
751 
752 	  case SLMIOGMFEED:	/* get manual feed */
753 		return( -EINVAL );
754 
755 	  case SLMIOSPSIZE:	/* set paper size */
756 		return( -EINVAL );
757 
758 	  case SLMIOSMFEED:	/* set manual feed */
759 		return( -EINVAL );
760 
761 	}
762 	return( -EINVAL );
763 }
764 
765 
766 /* ---------------------------------------------------------------------- */
767 /*							 Opening and Closing						  */
768 
769 
slm_open(struct inode * inode,struct file * file)770 static int slm_open( struct inode *inode, struct file *file )
771 
772 {	int device;
773 	struct slm *sip;
774 
775 	device = MINOR(inode->i_rdev);
776 	if (device >= N_SLM_Printers)
777 		return( -ENXIO );
778 	sip = &slm_info[device];
779 
780 	if (file->f_mode & 2) {
781 		/* open for writing is exclusive */
782 		if (sip->wbusy)
783 			return( -EBUSY );
784 		sip->wbusy = 1;
785 	}
786 	if (file->f_mode & 1) {
787 		/* open for writing is exclusive */
788 		if (sip->rbusy)
789 			return( -EBUSY );
790 		sip->rbusy = 1;
791 	}
792 
793 	return( 0 );
794 }
795 
796 
slm_release(struct inode * inode,struct file * file)797 static int slm_release( struct inode *inode, struct file *file )
798 
799 {	int device;
800 	struct slm *sip;
801 
802 	device = MINOR(inode->i_rdev);
803 	sip = &slm_info[device];
804 
805 	lock_kernel();
806 	if (file->f_mode & 2)
807 		sip->wbusy = 0;
808 	if (file->f_mode & 1)
809 		sip->rbusy = 0;
810 	unlock_kernel();
811 
812 	return( 0 );
813 }
814 
815 
816 /* ---------------------------------------------------------------------- */
817 /*						 ACSI Primitives for the SLM					  */
818 
819 
slm_req_sense(int device)820 static int slm_req_sense( int device )
821 
822 {	int			stat, rv;
823 	struct slm *sip = &slm_info[device];
824 
825 	stdma_lock( NULL, NULL );
826 
827 	CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun );
828 	if (!acsicmd_nodma( slmreqsense_cmd, 0 ) ||
829 		(stat = acsi_getstatus()) < 0)
830 		rv = SLMSTAT_ACSITO;
831 	else
832 		rv = stat & 0x1f;
833 
834 	ENABLE_IRQ();
835 	stdma_release();
836 	return( rv );
837 }
838 
839 
slm_mode_sense(int device,char * buffer,int abs_flag)840 static int slm_mode_sense( int device, char *buffer, int abs_flag )
841 
842 {	unsigned char	stat, len;
843 	int				rv = 0;
844 	struct slm		*sip = &slm_info[device];
845 
846 	stdma_lock( NULL, NULL );
847 
848 	CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun );
849 	slmmsense_cmd[5] = abs_flag ? 0x80 : 0;
850 	if (!acsicmd_nodma( slmmsense_cmd, 0 )) {
851 		rv = SLMSTAT_ACSITO;
852 		goto the_end;
853 	}
854 
855 	if (!acsi_extstatus( &stat, 1 )) {
856 		acsi_end_extstatus();
857 		rv = SLMSTAT_ACSITO;
858 		goto the_end;
859 	}
860 
861 	if (!acsi_extstatus( &len, 1 )) {
862 		acsi_end_extstatus();
863 		rv = SLMSTAT_ACSITO;
864 		goto the_end;
865 	}
866 	buffer[0] = len;
867 	if (!acsi_extstatus( buffer+1, len )) {
868 		acsi_end_extstatus();
869 		rv = SLMSTAT_ACSITO;
870 		goto the_end;
871 	}
872 
873 	acsi_end_extstatus();
874 	rv = stat & 0x1f;
875 
876   the_end:
877 	ENABLE_IRQ();
878 	stdma_release();
879 	return( rv );
880 }
881 
882 
883 #if 0
884 /* currently unused */
885 static int slm_mode_select( int device, char *buffer, int len,
886 							int default_flag )
887 
888 {	int			stat, rv;
889 	struct slm	*sip = &slm_info[device];
890 
891 	stdma_lock( NULL, NULL );
892 
893 	CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun );
894 	slmmselect_cmd[5] = default_flag ? 0x80 : 0;
895 	if (!acsicmd_nodma( slmmselect_cmd, 0 )) {
896 		rv = SLMSTAT_ACSITO;
897 		goto the_end;
898 	}
899 
900 	if (!default_flag) {
901 		unsigned char c = len;
902 		if (!acsi_extcmd( &c, 1 )) {
903 			rv = SLMSTAT_ACSITO;
904 			goto the_end;
905 		}
906 		if (!acsi_extcmd( buffer, len )) {
907 			rv = SLMSTAT_ACSITO;
908 			goto the_end;
909 		}
910 	}
911 
912 	stat = acsi_getstatus();
913 	rv = (stat < 0 ? SLMSTAT_ACSITO : stat);
914 
915   the_end:
916 	ENABLE_IRQ();
917 	stdma_release();
918 	return( rv );
919 }
920 #endif
921 
922 
slm_get_pagesize(int device,int * w,int * h)923 static int slm_get_pagesize( int device, int *w, int *h )
924 
925 {	char	buf[256];
926 	int		stat;
927 
928 	stat = slm_mode_sense( device, buf, 0 );
929 	ENABLE_IRQ();
930 	stdma_release();
931 
932 	if (stat != SLMSTAT_OK)
933 		return( -EIO );
934 
935 	*w = (buf[3] << 8) | buf[4];
936 	*h = (buf[1] << 8) | buf[2];
937 	return( 0 );
938 }
939 
940 
941 /* ---------------------------------------------------------------------- */
942 /*								Initialization							  */
943 
944 
attach_slm(int target,int lun)945 int attach_slm( int target, int lun )
946 
947 {	static int	did_register;
948 	int			len;
949 
950 	if (N_SLM_Printers >= MAX_SLM) {
951 		printk( KERN_WARNING "Too much SLMs\n" );
952 		return( 0 );
953 	}
954 
955 	/* do an INQUIRY */
956 	udelay(100);
957 	CMDSET_TARG_LUN( slminquiry_cmd, target, lun );
958 	if (!acsicmd_nodma( slminquiry_cmd, 0 )) {
959 	  inq_timeout:
960 		printk( KERN_ERR "SLM inquiry command timed out.\n" );
961 	  inq_fail:
962 		acsi_end_extstatus();
963 		return( 0 );
964 	}
965 	/* read status and header of return data */
966 	if (!acsi_extstatus( SLMBuffer, 6 ))
967 		goto inq_timeout;
968 
969 	if (SLMBuffer[1] != 2) { /* device type == printer? */
970 		printk( KERN_ERR "SLM inquiry returned device type != printer\n" );
971 		goto inq_fail;
972 	}
973 	len = SLMBuffer[5];
974 
975 	/* read id string */
976 	if (!acsi_extstatus( SLMBuffer, len ))
977 		goto inq_timeout;
978 	acsi_end_extstatus();
979 	SLMBuffer[len] = 0;
980 
981 	if (!did_register) {
982 		did_register = 1;
983 	}
984 
985 	slm_info[N_SLM_Printers].target = target;
986 	slm_info[N_SLM_Printers].lun    = lun;
987 	slm_info[N_SLM_Printers].wbusy  = 0;
988 	slm_info[N_SLM_Printers].rbusy  = 0;
989 
990 	printk( KERN_INFO "  Printer: %s\n", SLMBuffer );
991 	printk( KERN_INFO "Detected slm%d at id %d lun %d\n",
992 			N_SLM_Printers, target, lun );
993 	N_SLM_Printers++;
994 	return( 1 );
995 }
996 
997 static devfs_handle_t devfs_handle;
998 
slm_init(void)999 int slm_init( void )
1000 
1001 {
1002 	if (devfs_register_chrdev( MAJOR_NR, "slm", &slm_fops )) {
1003 		printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", MAJOR_NR );
1004 		return -EBUSY;
1005 	}
1006 
1007 	if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, "SLM" ))) {
1008 		printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" );
1009 		devfs_unregister_chrdev( MAJOR_NR, "slm" );
1010 		return -ENOMEM;
1011 	}
1012 	BufferP = SLMBuffer;
1013 	SLMState = IDLE;
1014 
1015 	devfs_handle = devfs_mk_dir (NULL, "slm", NULL);
1016 	devfs_register_series (devfs_handle, "%u", MAX_SLM, DEVFS_FL_DEFAULT,
1017 			       MAJOR_NR, 0, S_IFCHR | S_IRUSR | S_IWUSR,
1018 			       &slm_fops, NULL);
1019 	return 0;
1020 }
1021 
1022 #ifdef MODULE
1023 
1024 /* from acsi.c */
1025 void acsi_attach_SLMs( int (*attach_func)( int, int ) );
1026 
init_module(void)1027 int init_module(void)
1028 {
1029 	int err;
1030 
1031 	if ((err = slm_init()))
1032 		return( err );
1033 	/* This calls attach_slm() for every target/lun where acsi.c detected a
1034 	 * printer */
1035 	acsi_attach_SLMs( attach_slm );
1036 	return( 0 );
1037 }
1038 
cleanup_module(void)1039 void cleanup_module(void)
1040 {
1041 	devfs_unregister (devfs_handle);
1042 	if (devfs_unregister_chrdev( MAJOR_NR, "slm" ) != 0)
1043 		printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
1044 	atari_stram_free( SLMBuffer );
1045 }
1046 #endif
1047