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