File: /usr/src/linux/drivers/block/acsi_slm.c

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     
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     
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     
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     	unsigned long page;
371     	int length;
372     	int end;
373     
374     	if (count < 0)
375     		return( -EINVAL );
376     	if (!(page = __get_free_page( GFP_KERNEL )))
377     		return( -ENOMEM );
378     	
379     	length = slm_getstats( (char *)page, MINOR(node->i_rdev) );
380     	if (length < 0) {
381     		count = length;
382     		goto out;
383     	}
384     	if (file->f_pos >= length) {
385     		count = 0;
386     		goto out;
387     	}
388     	if (count + file->f_pos > length)
389     		count = length - file->f_pos;
390     	end = count + file->f_pos;
391     	if (copy_to_user(buf, (char *)page + file->f_pos, count)) {
392     		count = -EFAULT;
393     		goto out;
394     	}
395     	file->f_pos = end;
396     out:	free_page( page );
397     	return( count );
398     }
399     
400     
401     /* ---------------------------------------------------------------------- */
402     /*								   Printing								  */
403     
404     
405     static void start_print( int device )
406     
407     {	struct slm *sip = &slm_info[device];
408     	unsigned char	*cmd;
409     	unsigned long	paddr;
410     	int				i;
411     	
412     	stdma_lock( slm_interrupt, NULL );
413     
414     	CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun );
415     	cmd = slmprint_cmd;
416     	paddr = virt_to_phys( SLMBuffer );
417     	dma_cache_maintenance( paddr, virt_to_phys(BufferP)-paddr, 1 );
418     	DISABLE_IRQ();
419     
420     	/* Low on A1 */
421     	dma_wd.dma_mode_status = 0x88;
422     	MFPDELAY();
423     
424     	/* send the command bytes except the last */
425     	for( i = 0; i < 5; ++i ) {
426     		DMA_LONG_WRITE( *cmd++, 0x8a );
427     		udelay(20);
428     		if (!acsi_wait_for_IRQ( HZ/2 )) {
429     			SLMError = 1;
430     			return; /* timeout */
431     		}
432     	}
433     	/* last command byte */
434     	DMA_LONG_WRITE( *cmd++, 0x82 );
435     	MFPDELAY();
436     	/* set DMA address */
437     	set_dma_addr( paddr );
438     	/* program DMA for write and select sector counter reg */
439     	dma_wd.dma_mode_status = 0x192;
440     	MFPDELAY();
441     	/* program for 255*512 bytes and start DMA */
442     	DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
443     
444     #ifndef SLM_CONT_CNT_REPROG
445     	SLMCurAddr = paddr;
446     	SLMEndAddr = paddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
447     #endif
448     	START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize ));
449     #if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG)
450     	printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
451     			SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
452     #endif
453     	
454     	ENABLE_IRQ();
455     }
456     
457     
458     /* Only called when an error happened or at the end of a page */
459     
460     static void slm_interrupt(int irc, void *data, struct pt_regs *fp)
461     
462     {	unsigned long	addr;
463     	int				stat;
464     	
465     	STOP_TIMER();
466     	addr = get_dma_addr();
467     	stat = acsi_getstatus();
468     	SLMError = (stat < 0)             ? SLMSTAT_ACSITO :
469     		       (addr < virt_to_phys(BufferP)) ? SLMSTAT_NOTALL :
470     									    stat;
471     
472     	dma_wd.dma_mode_status = 0x80;
473     	MFPDELAY();
474     #ifdef DEBUG
475     	printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr, SLMError );
476     #endif
477     
478     	wake_up( &print_wait );
479     	stdma_release();
480     	ENABLE_IRQ();
481     }
482     
483     
484     static void slm_test_ready( unsigned long dummy )
485     
486     {
487     #ifdef SLM_CONT_CNT_REPROG
488     	/* program for 255*512 bytes again */
489     	dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
490     	START_TIMER( DMA_TIME_FOR(0) );
491     #ifdef DEBUG
492     	printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
493     			DMA_TIME_FOR(0), get_dma_addr() );
494     #endif
495     	
496     #else /* !SLM_CONT_CNT_REPROG */
497     
498     	unsigned long	flags, addr;
499     	int				d, ti;
500     #ifdef DEBUG
501     	struct timeval start_tm, end_tm;
502     	int			   did_wait = 0;
503     #endif
504     
505     	save_flags(flags);
506     	cli();
507     	
508     	addr = get_dma_addr();
509     	if ((d = SLMEndAddr - addr) > 0) {
510     		restore_flags(flags);
511     		
512     		/* slice not yet finished, decide whether to start another timer or to
513     		 * busy-wait */
514     		ti = DMA_TIME_FOR( d );
515     		if (ti > 0) {
516     #ifdef DEBUG
517     			printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
518     					ti, d );
519     #endif
520     			START_TIMER( ti );
521     			return;
522     		}
523     		/* wait for desired end address to be reached */
524     #ifdef DEBUG
525     		do_gettimeofday( &start_tm );
526     		did_wait = 1;
527     #endif
528     		cli();
529     		while( get_dma_addr() < SLMEndAddr )
530     			barrier();
531     	}
532     
533     	/* slice finished, start next one */
534     	SLMCurAddr += SLMSliceSize;
535     
536     #ifdef SLM_CONTINUOUS_DMA
537     	/* program for 255*512 bytes again */
538     	dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
539     #else
540     	/* set DMA address;
541     	 * add 2 bytes for the ones in the SLM controller FIFO! */
542     	set_dma_addr( SLMCurAddr + 2 );
543     	/* toggle DMA to write and select sector counter reg */
544     	dma_wd.dma_mode_status = 0x92;
545     	MFPDELAY();
546     	dma_wd.dma_mode_status = 0x192;
547     	MFPDELAY();
548     	/* program for 255*512 bytes and start DMA */
549     	DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
550     #endif
551     	
552     	restore_flags(flags);
553     
554     #ifdef DEBUG
555     	if (did_wait) {
556     		int ms;
557     		do_gettimeofday( &end_tm );
558     		ms = (end_tm.tv_sec*1000000+end_tm.tv_usec) -
559     			 (start_tm.tv_sec*1000000+start_tm.tv_usec); 
560     		printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n",
561     				ms/1000, ms%1000, d );
562     	}
563     	else
564     		printk( "SLM: didn't wait (!)\n" );
565     #endif
566     
567     	if ((unsigned char *)PTOV( SLMCurAddr + SLMSliceSize ) >= BufferP) {
568     		/* will be last slice, no timer necessary */
569     #ifdef DEBUG
570     		printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
571     				SLMCurAddr, SLMEndAddr );
572     #endif
573     	}
574     	else {
575     		/* not last slice */
576     		SLMEndAddr = SLMCurAddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
577     		START_TIMER( DMA_TIME_FOR( SLMSliceSize ));
578     #ifdef DEBUG
579     		printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
580     				SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
581     #endif
582     	}
583     #endif /* SLM_CONT_CNT_REPROG */
584     }
585     
586     
587     static void set_dma_addr( unsigned long paddr )
588     
589     {	unsigned long	flags;
590     	
591     	save_flags(flags);  
592     	cli();
593     	dma_wd.dma_lo = (unsigned char)paddr;
594     	paddr >>= 8;
595     	MFPDELAY();
596     	dma_wd.dma_md = (unsigned char)paddr;
597     	paddr >>= 8;
598     	MFPDELAY();
599     	if (ATARIHW_PRESENT( EXTD_DMA ))
600     		st_dma_ext_dmahi = (unsigned short)paddr;
601     	else
602     		dma_wd.dma_hi = (unsigned char)paddr;
603     	MFPDELAY();
604     	restore_flags(flags);
605     }
606     
607     
608     static unsigned long get_dma_addr( void )
609     
610     {	unsigned long	addr;
611     	
612     	addr = dma_wd.dma_lo & 0xff;
613     	MFPDELAY();
614     	addr |= (dma_wd.dma_md & 0xff) << 8;
615     	MFPDELAY();
616     	addr |= (dma_wd.dma_hi & 0xff) << 16;
617     	MFPDELAY();
618     
619     	return( addr );
620     }
621     
622     
623     static ssize_t slm_write( struct file *file, const char *buf, size_t count,
624     						  loff_t *ppos )
625     
626     {
627     	struct inode *node = file->f_dentry->d_inode;
628     	int		device = MINOR( node->i_rdev );
629     	int		n, filled, w, h;
630     
631     	while( SLMState == PRINTING ||
632     		   (SLMState == FILLING && SLMBufOwner != device) ) {
633     		interruptible_sleep_on( &slm_wait );
634     		if (signal_pending(current))
635     			return( -ERESTARTSYS );
636     	}
637     	if (SLMState == IDLE) {
638     		/* first data of page: get current page size  */
639     		if (slm_get_pagesize( device, &w, &h ))
640     			return( -EIO );
641     		BufferSize = w*h/8;
642     		if (BufferSize > SLM_BUFFER_SIZE)
643     			return( -ENOMEM );
644     
645     		SLMState = FILLING;
646     		SLMBufOwner = device;
647     	}
648     
649     	n = count;
650     	filled = BufferP - SLMBuffer;
651     	if (filled + n > BufferSize)
652     		n = BufferSize - filled;
653     
654     	if (copy_from_user(BufferP, buf, n))
655     		return -EFAULT;
656     	BufferP += n;
657     	filled += n;
658     
659     	if (filled == BufferSize) {
660     		/* Check the paper size again! The user may have switched it in the
661     		 * time between starting the data and finishing them. Would end up in
662     		 * a trashy page... */
663     		if (slm_get_pagesize( device, &w, &h ))
664     			return( -EIO );
665     		if (BufferSize != w*h/8) {
666     			printk( KERN_NOTICE "slm%d: page size changed while printing\n",
667     					device );
668     			return( -EAGAIN );
669     		}
670     
671     		SLMState = PRINTING;
672     		/* choose a slice size that is a multiple of the line size */
673     #ifndef SLM_CONT_CNT_REPROG
674     		SLMSliceSize = SLM_SLICE_SIZE(w);
675     #endif
676     		
677     		start_print( device );
678     		sleep_on( &print_wait );
679     		if (SLMError && IS_REAL_ERROR(SLMError)) {
680     			printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) );
681     			n = -EIO;
682     		}
683     
684     		SLMState = IDLE;
685     		BufferP = SLMBuffer;
686     		wake_up_interruptible( &slm_wait );
687     	}
688     	
689     	return( n );
690     }
691     
692     
693     /* ---------------------------------------------------------------------- */
694     /*							   ioctl Functions							  */
695     
696     
697     static int slm_ioctl( struct inode *inode, struct file *file,
698     					  unsigned int cmd, unsigned long arg )
699     
700     {	int		device = MINOR( inode->i_rdev ), err;
701     	
702     	/* I can think of setting:
703     	 *  - manual feed
704     	 *  - paper format
705     	 *  - copy count
706     	 *  - ...
707     	 * but haven't implemented that yet :-)
708     	 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
709     	 */
710     	switch( cmd ) {
711     
712     	  case SLMIORESET:		/* reset buffer, i.e. empty the buffer */
713     		if (!(file->f_mode & 2))
714     			return( -EINVAL );
715     		if (SLMState == PRINTING)
716     			return( -EBUSY );
717     		SLMState = IDLE;
718     		BufferP = SLMBuffer;
719     		wake_up_interruptible( &slm_wait );
720     		return( 0 );
721     		
722     	  case SLMIOGSTAT: {	/* get status */
723     		int stat;
724     		char *str;
725     
726     		stat = slm_req_sense( device );
727     		if (arg) {
728     			str = slm_errstr( stat );
729     			if (put_user(stat,
730         	    	    	    	     (long *)&((struct SLM_status *)arg)->stat))
731         	    	    	    	return -EFAULT;
732     			if (copy_to_user( ((struct SLM_status *)arg)->str, str,
733     						 strlen(str) + 1))
734     				return -EFAULT;
735     		}
736     		return( stat );
737     	  }
738     		
739     	  case SLMIOGPSIZE: {	/* get paper size */
740     		int w, h;
741     		
742     		if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
743     		
744         	    	if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
745     			return -EFAULT;
746     		if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height))
747     			return -EFAULT;
748     		return( 0 );
749     	  }
750     		
751     	  case SLMIOGMFEED:	/* get manual feed */
752     		return( -EINVAL );
753     
754     	  case SLMIOSPSIZE:	/* set paper size */
755     		return( -EINVAL );
756     
757     	  case SLMIOSMFEED:	/* set manual feed */
758     		return( -EINVAL );
759     
760     	}
761     	return( -EINVAL );
762     }
763     
764     
765     /* ---------------------------------------------------------------------- */
766     /*							 Opening and Closing						  */
767     
768     
769     static int slm_open( struct inode *inode, struct file *file )
770     
771     {	int device;
772     	struct slm *sip;
773     	
774     	device = MINOR(inode->i_rdev);
775     	if (device >= N_SLM_Printers)
776     		return( -ENXIO );
777     	sip = &slm_info[device];
778     
779     	if (file->f_mode & 2) {
780     		/* open for writing is exclusive */
781     		if (sip->wbusy)
782     			return( -EBUSY );
783     		sip->wbusy = 1;
784     	}
785     	if (file->f_mode & 1) {
786     		/* open for writing is exclusive */
787     		if (sip->rbusy)
788     			return( -EBUSY );
789     		sip->rbusy = 1;
790     	}
791     
792     	return( 0 );
793     }
794     
795     
796     static int slm_release( struct inode *inode, struct file *file )
797     
798     {	int device;
799     	struct slm *sip;
800     	
801     	device = MINOR(inode->i_rdev);
802     	sip = &slm_info[device];
803     
804     	lock_kernel();
805     	if (file->f_mode & 2)
806     		sip->wbusy = 0;
807     	if (file->f_mode & 1)
808     		sip->rbusy = 0;
809     	unlock_kernel();
810     	
811     	return( 0 );
812     }
813     
814     
815     /* ---------------------------------------------------------------------- */
816     /*						 ACSI Primitives for the SLM					  */
817     
818     
819     static int slm_req_sense( int device )
820     
821     {	int			stat, rv;
822     	struct slm *sip = &slm_info[device];
823     	
824     	stdma_lock( NULL, NULL );
825     
826     	CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun );
827     	if (!acsicmd_nodma( slmreqsense_cmd, 0 ) ||
828     		(stat = acsi_getstatus()) < 0)
829     		rv = SLMSTAT_ACSITO;
830     	else
831     		rv = stat & 0x1f;
832     
833     	ENABLE_IRQ();
834     	stdma_release();
835     	return( rv );
836     }
837     
838     
839     static int slm_mode_sense( int device, char *buffer, int abs_flag )
840     
841     {	unsigned char	stat, len;
842     	int				rv = 0;
843     	struct slm		*sip = &slm_info[device];
844     	
845     	stdma_lock( NULL, NULL );
846     
847     	CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun );
848     	slmmsense_cmd[5] = abs_flag ? 0x80 : 0;
849     	if (!acsicmd_nodma( slmmsense_cmd, 0 )) {
850     		rv = SLMSTAT_ACSITO;
851     		goto the_end;
852     	}
853     
854     	if (!acsi_extstatus( &stat, 1 )) {
855     		acsi_end_extstatus();
856     		rv = SLMSTAT_ACSITO;
857     		goto the_end;
858     	}
859     	
860     	if (!acsi_extstatus( &len, 1 )) {
861     		acsi_end_extstatus();
862     		rv = SLMSTAT_ACSITO;
863     		goto the_end;
864     	}
865     	buffer[0] = len;
866     	if (!acsi_extstatus( buffer+1, len )) {
867     		acsi_end_extstatus();
868     		rv = SLMSTAT_ACSITO;
869     		goto the_end;
870     	}
871     	
872     	acsi_end_extstatus();
873     	rv = stat & 0x1f;
874     
875       the_end:
876     	ENABLE_IRQ();
877     	stdma_release();
878     	return( rv );
879     }
880     
881     
882     #if 0
883     /* currently unused */
884     static int slm_mode_select( int device, char *buffer, int len,
885     							int default_flag )
886     
887     {	int			stat, rv;
888     	struct slm	*sip = &slm_info[device];
889     	
890     	stdma_lock( NULL, NULL );
891     
892     	CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun );
893     	slmmselect_cmd[5] = default_flag ? 0x80 : 0;
894     	if (!acsicmd_nodma( slmmselect_cmd, 0 )) {
895     		rv = SLMSTAT_ACSITO;
896     		goto the_end;
897     	}
898     
899     	if (!default_flag) {
900     		unsigned char c = len;
901     		if (!acsi_extcmd( &c, 1 )) {
902     			rv = SLMSTAT_ACSITO;
903     			goto the_end;
904     		}
905     		if (!acsi_extcmd( buffer, len )) {
906     			rv = SLMSTAT_ACSITO;
907     			goto the_end;
908     		}
909     	}
910     	
911     	stat = acsi_getstatus();
912     	rv = (stat < 0 ? SLMSTAT_ACSITO : stat);
913     
914       the_end:
915     	ENABLE_IRQ();
916     	stdma_release();
917     	return( rv );
918     }
919     #endif
920     
921     
922     static int slm_get_pagesize( int device, int *w, int *h )
923     
924     {	char	buf[256];
925     	int		stat;
926     	
927     	stat = slm_mode_sense( device, buf, 0 );
928     	ENABLE_IRQ();
929     	stdma_release();
930     
931     	if (stat != SLMSTAT_OK)
932     		return( -EIO );
933     
934     	*w = (buf[3] << 8) | buf[4];
935     	*h = (buf[1] << 8) | buf[2];
936     	return( 0 );
937     }
938     
939     
940     /* ---------------------------------------------------------------------- */
941     /*								Initialization							  */
942     
943     
944     int attach_slm( int target, int lun )
945     
946     {	static int	did_register;
947     	int			len;
948     
949     	if (N_SLM_Printers >= MAX_SLM) {
950     		printk( KERN_WARNING "Too much SLMs\n" );
951     		return( 0 );
952     	}
953     	
954     	/* do an INQUIRY */
955     	udelay(100);
956     	CMDSET_TARG_LUN( slminquiry_cmd, target, lun );
957     	if (!acsicmd_nodma( slminquiry_cmd, 0 )) {
958     	  inq_timeout:
959     		printk( KERN_ERR "SLM inquiry command timed out.\n" );
960     	  inq_fail:
961     		acsi_end_extstatus();
962     		return( 0 );
963     	}
964     	/* read status and header of return data */
965     	if (!acsi_extstatus( SLMBuffer, 6 ))
966     		goto inq_timeout;
967     
968     	if (SLMBuffer[1] != 2) { /* device type == printer? */
969     		printk( KERN_ERR "SLM inquiry returned device type != printer\n" );
970     		goto inq_fail;
971     	}
972     	len = SLMBuffer[5];
973     	
974     	/* read id string */
975     	if (!acsi_extstatus( SLMBuffer, len ))
976     		goto inq_timeout;
977     	acsi_end_extstatus();
978     	SLMBuffer[len] = 0;
979     
980     	if (!did_register) {
981     		did_register = 1;
982     	}
983     
984     	slm_info[N_SLM_Printers].target = target;
985     	slm_info[N_SLM_Printers].lun    = lun;
986     	slm_info[N_SLM_Printers].wbusy  = 0;
987     	slm_info[N_SLM_Printers].rbusy  = 0;
988     	
989     	printk( KERN_INFO "  Printer: %s\n", SLMBuffer );
990     	printk( KERN_INFO "Detected slm%d at id %d lun %d\n",
991     			N_SLM_Printers, target, lun );
992     	N_SLM_Printers++;
993     	return( 1 );
994     }
995     
996     static devfs_handle_t devfs_handle;
997     
998     int slm_init( void )
999     
1000     {
1001     	if (devfs_register_chrdev( MAJOR_NR, "slm", &slm_fops )) {
1002     		printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", MAJOR_NR );
1003     		return -EBUSY;
1004     	}
1005     	
1006     	if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, NULL, "SLM" ))) {
1007     		printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" );
1008     		devfs_unregister_chrdev( MAJOR_NR, "slm" );
1009     		return -ENOMEM;
1010     	}
1011     	BufferP = SLMBuffer;
1012     	SLMState = IDLE;
1013     	
1014     	devfs_handle = devfs_mk_dir (NULL, "slm", NULL);
1015     	devfs_register_series (devfs_handle, "%u", MAX_SLM, DEVFS_FL_DEFAULT,
1016     			       MAJOR_NR, 0, S_IFCHR | S_IRUSR | S_IWUSR,
1017     			       &slm_fops, NULL);
1018     	return 0;
1019     }
1020     
1021     #ifdef MODULE
1022     
1023     /* from acsi.c */
1024     void acsi_attach_SLMs( int (*attach_func)( int, int ) );
1025     
1026     int init_module(void)
1027     {
1028     	int err;
1029     
1030     	if ((err = slm_init()))
1031     		return( err );
1032     	/* This calls attach_slm() for every target/lun where acsi.c detected a
1033     	 * printer */
1034     	acsi_attach_SLMs( attach_slm );
1035     	return( 0 );
1036     }
1037     
1038     void cleanup_module(void)
1039     {
1040     	devfs_unregister (devfs_handle);
1041     	if (devfs_unregister_chrdev( MAJOR_NR, "slm" ) != 0)
1042     		printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
1043     	atari_stram_free( SLMBuffer );
1044     }
1045     #endif
1046