Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / block / acsi_slm.c
blob35bab96feb184df38910959e3541656f60cb06b4
1 /*
2 * acsi_slm.c -- Device driver for the Atari SLM laser printer
4 * Copyright 1995 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
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 *
14 Notes:
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.
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:
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.
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.
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)...
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).
55 #include <linux/module.h>
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/malloc.h>
68 #include <linux/devfs_fs_kernel.h>
69 #include <linux/smp_lock.h>
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>
82 #undef DEBUG
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
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.
96 #define SLM_CONT_CNT_REPROG
98 #define MAJOR_NR ACSI_MAJOR
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)
106 #define START_TIMER(to) mod_timer(&slm_timer, jiffies + (to))
107 #define STOP_TIMER() del_timer(&slm_timer)
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
119 #define MAX_SLM 2
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];
128 int N_SLM_Printers = 0;
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 */
135 typedef enum { IDLE, FILLING, PRINTING } SLMSTATE;
136 static SLMSTATE SLMState;
137 static int SLMBufOwner; /* SLM# currently using the buffer */
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;
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 */
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 */
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"
205 #define N_ERRORS (sizeof(SLMErrors)/sizeof(*SLMErrors))
207 /* real (driver caused) error? */
208 #define IS_REAL_ERROR(x) (x > 0x10)
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 }
221 #define N_STD_SIZES (sizeof(StdPageSize)/sizeof(*StdPageSize))
223 #define SLM_BUFFER_SIZE (2336*3386/8) /* A4 for now */
224 #define SLM_DMA_AMOUNT 255 /* #sectors to program the DMA for */
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
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
245 /***************************** Prototypes *****************************/
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 );
270 /************************* End of Prototypes **************************/
273 static struct timer_list slm_timer = { function: slm_test_ready };
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,
285 /* ---------------------------------------------------------------------- */
286 /* Status Functions */
289 static char *slm_errstr( int stat )
291 { char *p;
292 static char str[22];
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 );
302 static int slm_getstats( char *buffer, int device )
304 { int len = 0, stat, i, w, h;
305 unsigned char buf[256];
307 stat = slm_mode_sense( device, buf, 0 );
308 if (IS_REAL_ERROR(stat))
309 return( -EIO );
311 #define SHORTDATA(i) ((buf[i] << 8) | buf[i+1])
312 #define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off")
314 w = SHORTDATA( 3 );
315 h = SHORTDATA( 1 );
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 );
322 for( i = 0; i < N_STD_SIZES; ++i ) {
323 if (w == StdPageSize[i].w && h == StdPageSize[i].h)
324 break;
326 if (i < N_STD_SIZES)
327 len += sprintf( buffer+len, " (%s)", StdPageSize[i].name );
328 buffer[len++] = '\n';
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 ) );
361 return( len );
365 static ssize_t slm_read( struct file *file, char *buf, size_t count,
366 loff_t *ppos )
369 struct inode *node = file->f_dentry->d_inode;
370 unsigned long page;
371 int length;
372 int end;
374 if (count < 0)
375 return( -EINVAL );
376 if (!(page = __get_free_page( GFP_KERNEL )))
377 return( -ENOMEM );
379 length = slm_getstats( (char *)page, MINOR(node->i_rdev) );
380 if (length < 0) {
381 free_page( page );
382 return( length );
384 if (file->f_pos >= length) {
385 free_page( page );
386 return( 0 );
388 if (count + file->f_pos > length)
389 count = length - file->f_pos;
390 end = count + file->f_pos;
391 copy_to_user( buf, (char *)page + file->f_pos, count );
392 free_page( page );
393 file->f_pos = end;
394 return( count );
398 /* ---------------------------------------------------------------------- */
399 /* Printing */
402 static void start_print( int device )
404 { struct slm *sip = &slm_info[device];
405 unsigned char *cmd;
406 unsigned long paddr;
407 int i;
409 stdma_lock( slm_interrupt, NULL );
411 CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun );
412 cmd = slmprint_cmd;
413 paddr = virt_to_phys( SLMBuffer );
414 dma_cache_maintenance( paddr, virt_to_phys(BufferP)-paddr, 1 );
415 DISABLE_IRQ();
417 /* Low on A1 */
418 dma_wd.dma_mode_status = 0x88;
419 MFPDELAY();
421 /* send the command bytes except the last */
422 for( i = 0; i < 5; ++i ) {
423 DMA_LONG_WRITE( *cmd++, 0x8a );
424 udelay(20);
425 if (!acsi_wait_for_IRQ( HZ/2 )) {
426 SLMError = 1;
427 return; /* timeout */
430 /* last command byte */
431 DMA_LONG_WRITE( *cmd++, 0x82 );
432 MFPDELAY();
433 /* set DMA address */
434 set_dma_addr( paddr );
435 /* program DMA for write and select sector counter reg */
436 dma_wd.dma_mode_status = 0x192;
437 MFPDELAY();
438 /* program for 255*512 bytes and start DMA */
439 DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
441 #ifndef SLM_CONT_CNT_REPROG
442 SLMCurAddr = paddr;
443 SLMEndAddr = paddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
444 #endif
445 START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize ));
446 #if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG)
447 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
448 SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
449 #endif
451 ENABLE_IRQ();
455 /* Only called when an error happened or at the end of a page */
457 static void slm_interrupt(int irc, void *data, struct pt_regs *fp)
459 { unsigned long addr;
460 int stat;
462 STOP_TIMER();
463 addr = get_dma_addr();
464 stat = acsi_getstatus();
465 SLMError = (stat < 0) ? SLMSTAT_ACSITO :
466 (addr < virt_to_phys(BufferP)) ? SLMSTAT_NOTALL :
467 stat;
469 dma_wd.dma_mode_status = 0x80;
470 MFPDELAY();
471 #ifdef DEBUG
472 printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr, SLMError );
473 #endif
475 wake_up( &print_wait );
476 stdma_release();
477 ENABLE_IRQ();
481 static void slm_test_ready( unsigned long dummy )
484 #ifdef SLM_CONT_CNT_REPROG
485 /* program for 255*512 bytes again */
486 dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
487 START_TIMER( DMA_TIME_FOR(0) );
488 #ifdef DEBUG
489 printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
490 DMA_TIME_FOR(0), get_dma_addr() );
491 #endif
493 #else /* !SLM_CONT_CNT_REPROG */
495 unsigned long flags, addr;
496 int d, ti;
497 #ifdef DEBUG
498 struct timeval start_tm, end_tm;
499 int did_wait = 0;
500 #endif
502 save_flags(flags);
503 cli();
505 addr = get_dma_addr();
506 if ((d = SLMEndAddr - addr) > 0) {
507 restore_flags(flags);
509 /* slice not yet finished, decide whether to start another timer or to
510 * busy-wait */
511 ti = DMA_TIME_FOR( d );
512 if (ti > 0) {
513 #ifdef DEBUG
514 printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
515 ti, d );
516 #endif
517 START_TIMER( ti );
518 return;
520 /* wait for desired end address to be reached */
521 #ifdef DEBUG
522 do_gettimeofday( &start_tm );
523 did_wait = 1;
524 #endif
525 cli();
526 while( get_dma_addr() < SLMEndAddr )
527 barrier();
530 /* slice finished, start next one */
531 SLMCurAddr += SLMSliceSize;
533 #ifdef SLM_CONTINUOUS_DMA
534 /* program for 255*512 bytes again */
535 dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
536 #else
537 /* set DMA address;
538 * add 2 bytes for the ones in the SLM controller FIFO! */
539 set_dma_addr( SLMCurAddr + 2 );
540 /* toggle DMA to write and select sector counter reg */
541 dma_wd.dma_mode_status = 0x92;
542 MFPDELAY();
543 dma_wd.dma_mode_status = 0x192;
544 MFPDELAY();
545 /* program for 255*512 bytes and start DMA */
546 DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
547 #endif
549 restore_flags(flags);
551 #ifdef DEBUG
552 if (did_wait) {
553 int ms;
554 do_gettimeofday( &end_tm );
555 ms = (end_tm.tv_sec*1000000+end_tm.tv_usec) -
556 (start_tm.tv_sec*1000000+start_tm.tv_usec);
557 printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n",
558 ms/1000, ms%1000, d );
560 else
561 printk( "SLM: didn't wait (!)\n" );
562 #endif
564 if ((unsigned char *)PTOV( SLMCurAddr + SLMSliceSize ) >= BufferP) {
565 /* will be last slice, no timer necessary */
566 #ifdef DEBUG
567 printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
568 SLMCurAddr, SLMEndAddr );
569 #endif
571 else {
572 /* not last slice */
573 SLMEndAddr = SLMCurAddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
574 START_TIMER( DMA_TIME_FOR( SLMSliceSize ));
575 #ifdef DEBUG
576 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
577 SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
578 #endif
580 #endif /* SLM_CONT_CNT_REPROG */
584 static void set_dma_addr( unsigned long paddr )
586 { unsigned long flags;
588 save_flags(flags);
589 cli();
590 dma_wd.dma_lo = (unsigned char)paddr;
591 paddr >>= 8;
592 MFPDELAY();
593 dma_wd.dma_md = (unsigned char)paddr;
594 paddr >>= 8;
595 MFPDELAY();
596 if (ATARIHW_PRESENT( EXTD_DMA ))
597 st_dma_ext_dmahi = (unsigned short)paddr;
598 else
599 dma_wd.dma_hi = (unsigned char)paddr;
600 MFPDELAY();
601 restore_flags(flags);
605 static unsigned long get_dma_addr( void )
607 { unsigned long addr;
609 addr = dma_wd.dma_lo & 0xff;
610 MFPDELAY();
611 addr |= (dma_wd.dma_md & 0xff) << 8;
612 MFPDELAY();
613 addr |= (dma_wd.dma_hi & 0xff) << 16;
614 MFPDELAY();
616 return( addr );
620 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
621 loff_t *ppos )
624 struct inode *node = file->f_dentry->d_inode;
625 int device = MINOR( node->i_rdev );
626 int n, filled, w, h;
628 while( SLMState == PRINTING ||
629 (SLMState == FILLING && SLMBufOwner != device) ) {
630 interruptible_sleep_on( &slm_wait );
631 if (signal_pending(current))
632 return( -ERESTARTSYS );
634 if (SLMState == IDLE) {
635 /* first data of page: get current page size */
636 if (slm_get_pagesize( device, &w, &h ))
637 return( -EIO );
638 BufferSize = w*h/8;
639 if (BufferSize > SLM_BUFFER_SIZE)
640 return( -ENOMEM );
642 SLMState = FILLING;
643 SLMBufOwner = device;
646 n = count;
647 filled = BufferP - SLMBuffer;
648 if (filled + n > BufferSize)
649 n = BufferSize - filled;
651 copy_from_user( BufferP, buf, n );
652 BufferP += n;
653 filled += n;
655 if (filled == BufferSize) {
656 /* Check the paper size again! The user may have switched it in the
657 * time between starting the data and finishing them. Would end up in
658 * a trashy page... */
659 if (slm_get_pagesize( device, &w, &h ))
660 return( -EIO );
661 if (BufferSize != w*h/8) {
662 printk( KERN_NOTICE "slm%d: page size changed while printing\n",
663 device );
664 return( -EAGAIN );
667 SLMState = PRINTING;
668 /* choose a slice size that is a multiple of the line size */
669 #ifndef SLM_CONT_CNT_REPROG
670 SLMSliceSize = SLM_SLICE_SIZE(w);
671 #endif
673 start_print( device );
674 sleep_on( &print_wait );
675 if (SLMError && IS_REAL_ERROR(SLMError)) {
676 printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) );
677 n = -EIO;
680 SLMState = IDLE;
681 BufferP = SLMBuffer;
682 wake_up_interruptible( &slm_wait );
685 return( n );
689 /* ---------------------------------------------------------------------- */
690 /* ioctl Functions */
693 static int slm_ioctl( struct inode *inode, struct file *file,
694 unsigned int cmd, unsigned long arg )
696 { int device = MINOR( inode->i_rdev ), err;
698 /* I can think of setting:
699 * - manual feed
700 * - paper format
701 * - copy count
702 * - ...
703 * but haven't implemented that yet :-)
704 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
706 switch( cmd ) {
708 case SLMIORESET: /* reset buffer, i.e. empty the buffer */
709 if (!(file->f_mode & 2))
710 return( -EINVAL );
711 if (SLMState == PRINTING)
712 return( -EBUSY );
713 SLMState = IDLE;
714 BufferP = SLMBuffer;
715 wake_up_interruptible( &slm_wait );
716 return( 0 );
718 case SLMIOGSTAT: { /* get status */
719 int stat;
720 char *str;
722 stat = slm_req_sense( device );
723 if (arg) {
724 str = slm_errstr( stat );
725 if (put_user(stat,
726 (long *)&((struct SLM_status *)arg)->stat))
727 return -EFAULT;
728 copy_to_user( ((struct SLM_status *)arg)->str, str,
729 strlen(str) + 1 );
731 return( stat );
734 case SLMIOGPSIZE: { /* get paper size */
735 int w, h;
737 err = verify_area( VERIFY_WRITE, (long *)arg,
738 sizeof(struct SLM_paper_size) );
739 if (err) return( err );
741 if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
743 if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
744 return -EFAULT;
745 if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height))
746 return -EFAULT;
747 return( 0 );
750 case SLMIOGMFEED: /* get manual feed */
751 return( -EINVAL );
753 case SLMIOSPSIZE: /* set paper size */
754 return( -EINVAL );
756 case SLMIOSMFEED: /* set manual feed */
757 return( -EINVAL );
760 return( -EINVAL );
764 /* ---------------------------------------------------------------------- */
765 /* Opening and Closing */
768 static int slm_open( struct inode *inode, struct file *file )
770 { int device;
771 struct slm *sip;
773 device = MINOR(inode->i_rdev);
774 if (device >= N_SLM_Printers)
775 return( -ENXIO );
776 sip = &slm_info[device];
778 if (file->f_mode & 2) {
779 /* open for writing is exclusive */
780 if (sip->wbusy)
781 return( -EBUSY );
782 sip->wbusy = 1;
784 if (file->f_mode & 1) {
785 /* open for writing is exclusive */
786 if (sip->rbusy)
787 return( -EBUSY );
788 sip->rbusy = 1;
791 return( 0 );
795 static int slm_release( struct inode *inode, struct file *file )
797 { int device;
798 struct slm *sip;
800 device = MINOR(inode->i_rdev);
801 sip = &slm_info[device];
803 lock_kernel();
804 if (file->f_mode & 2)
805 sip->wbusy = 0;
806 if (file->f_mode & 1)
807 sip->rbusy = 0;
808 unlock_kernel();
810 return( 0 );
814 /* ---------------------------------------------------------------------- */
815 /* ACSI Primitives for the SLM */
818 static int slm_req_sense( int device )
820 { int stat, rv;
821 struct slm *sip = &slm_info[device];
823 stdma_lock( NULL, NULL );
825 CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun );
826 if (!acsicmd_nodma( slmreqsense_cmd, 0 ) ||
827 (stat = acsi_getstatus()) < 0)
828 rv = SLMSTAT_ACSITO;
829 else
830 rv = stat & 0x1f;
832 ENABLE_IRQ();
833 stdma_release();
834 return( rv );
838 static int slm_mode_sense( int device, char *buffer, int abs_flag )
840 { unsigned char stat, len;
841 int rv = 0;
842 struct slm *sip = &slm_info[device];
844 stdma_lock( NULL, NULL );
846 CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun );
847 slmmsense_cmd[5] = abs_flag ? 0x80 : 0;
848 if (!acsicmd_nodma( slmmsense_cmd, 0 )) {
849 rv = SLMSTAT_ACSITO;
850 goto the_end;
853 if (!acsi_extstatus( &stat, 1 )) {
854 acsi_end_extstatus();
855 rv = SLMSTAT_ACSITO;
856 goto the_end;
859 if (!acsi_extstatus( &len, 1 )) {
860 acsi_end_extstatus();
861 rv = SLMSTAT_ACSITO;
862 goto the_end;
864 buffer[0] = len;
865 if (!acsi_extstatus( buffer+1, len )) {
866 acsi_end_extstatus();
867 rv = SLMSTAT_ACSITO;
868 goto the_end;
871 acsi_end_extstatus();
872 rv = stat & 0x1f;
874 the_end:
875 ENABLE_IRQ();
876 stdma_release();
877 return( rv );
881 #if 0
882 /* currently unused */
883 static int slm_mode_select( int device, char *buffer, int len,
884 int default_flag )
886 { int stat, rv;
887 struct slm *sip = &slm_info[device];
889 stdma_lock( NULL, NULL );
891 CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun );
892 slmmselect_cmd[5] = default_flag ? 0x80 : 0;
893 if (!acsicmd_nodma( slmmselect_cmd, 0 )) {
894 rv = SLMSTAT_ACSITO;
895 goto the_end;
898 if (!default_flag) {
899 unsigned char c = len;
900 if (!acsi_extcmd( &c, 1 )) {
901 rv = SLMSTAT_ACSITO;
902 goto the_end;
904 if (!acsi_extcmd( buffer, len )) {
905 rv = SLMSTAT_ACSITO;
906 goto the_end;
910 stat = acsi_getstatus();
911 rv = (stat < 0 ? SLMSTAT_ACSITO : stat);
913 the_end:
914 ENABLE_IRQ();
915 stdma_release();
916 return( rv );
918 #endif
921 static int slm_get_pagesize( int device, int *w, int *h )
923 { char buf[256];
924 int stat;
926 stat = slm_mode_sense( device, buf, 0 );
927 ENABLE_IRQ();
928 stdma_release();
930 if (stat != SLMSTAT_OK)
931 return( -EIO );
933 *w = (buf[3] << 8) | buf[4];
934 *h = (buf[1] << 8) | buf[2];
935 return( 0 );
939 /* ---------------------------------------------------------------------- */
940 /* Initialization */
943 int attach_slm( int target, int lun )
945 { static int did_register;
946 int len;
948 if (N_SLM_Printers >= MAX_SLM) {
949 printk( KERN_WARNING "Too much SLMs\n" );
950 return( 0 );
953 /* do an INQUIRY */
954 udelay(100);
955 CMDSET_TARG_LUN( slminquiry_cmd, target, lun );
956 if (!acsicmd_nodma( slminquiry_cmd, 0 )) {
957 inq_timeout:
958 printk( KERN_ERR "SLM inquiry command timed out.\n" );
959 inq_fail:
960 acsi_end_extstatus();
961 return( 0 );
963 /* read status and header of return data */
964 if (!acsi_extstatus( SLMBuffer, 6 ))
965 goto inq_timeout;
967 if (SLMBuffer[1] != 2) { /* device type == printer? */
968 printk( KERN_ERR "SLM inquiry returned device type != printer\n" );
969 goto inq_fail;
971 len = SLMBuffer[5];
973 /* read id string */
974 if (!acsi_extstatus( SLMBuffer, len ))
975 goto inq_timeout;
976 acsi_end_extstatus();
977 SLMBuffer[len] = 0;
979 if (!did_register) {
980 did_register = 1;
983 slm_info[N_SLM_Printers].target = target;
984 slm_info[N_SLM_Printers].lun = lun;
985 slm_info[N_SLM_Printers].wbusy = 0;
986 slm_info[N_SLM_Printers].rbusy = 0;
988 printk( KERN_INFO " Printer: %s\n", SLMBuffer );
989 printk( KERN_INFO "Detected slm%d at id %d lun %d\n",
990 N_SLM_Printers, target, lun );
991 N_SLM_Printers++;
992 return( 1 );
995 static devfs_handle_t devfs_handle;
997 int slm_init( void )
1000 if (devfs_register_chrdev( MAJOR_NR, "slm", &slm_fops )) {
1001 printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", MAJOR_NR );
1002 return -EBUSY;
1005 if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, NULL, "SLM" ))) {
1006 printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" );
1007 devfs_unregister_chrdev( MAJOR_NR, "slm" );
1008 return -ENOMEM;
1010 BufferP = SLMBuffer;
1011 SLMState = IDLE;
1013 devfs_handle = devfs_mk_dir (NULL, "slm", NULL);
1014 devfs_register_series (devfs_handle, "%u", MAX_SLM, DEVFS_FL_DEFAULT,
1015 MAJOR_NR, 0, S_IFCHR | S_IRUSR | S_IWUSR,
1016 &slm_fops, NULL);
1017 return 0;
1020 #ifdef MODULE
1022 /* from acsi.c */
1023 void acsi_attach_SLMs( int (*attach_func)( int, int ) );
1025 int init_module(void)
1027 int err;
1029 if ((err = slm_init()))
1030 return( err );
1031 /* This calls attach_slm() for every target/lun where acsi.c detected a
1032 * printer */
1033 acsi_attach_SLMs( attach_slm );
1034 return( 0 );
1037 void cleanup_module(void)
1039 devfs_unregister (devfs_handle);
1040 if (devfs_unregister_chrdev( MAJOR_NR, "slm" ) != 0)
1041 printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
1042 atari_stram_free( SLMBuffer );
1044 #endif