Import 2.1.118
[davej-history.git] / drivers / block / acsi_slm.c
blob66121340f1bf107753ff5f074ab48d2f18e8e465
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>
69 #include <asm/pgtable.h>
70 #include <asm/system.h>
71 #include <asm/uaccess.h>
72 #include <asm/atarihw.h>
73 #include <asm/atariints.h>
74 #include <asm/atari_acsi.h>
75 #include <asm/atari_stdma.h>
76 #include <asm/atari_stram.h>
77 #include <asm/atari_SLM.h>
80 #undef DEBUG
82 /* Define this if the page data are continuous in physical memory. That
83 * requires less reprogramming of the ST-DMA */
84 #define SLM_CONTINUOUS_DMA
86 /* Use continuous reprogramming of the ST-DMA counter register. This is
87 * --strictly speaking-- not allowed, Atari recommends not to look at the
88 * counter register while a DMA is going on. But I don't know if that applies
89 * only for reading the register, or also writing to it. Writing only works
90 * fine for me... The advantage is that the timing becomes absolutely
91 * uncritical: Just update each, say 200ms, the counter reg to its maximum,
92 * and the DMA will work until the status byte interrupt occurs.
94 #define SLM_CONT_CNT_REPROG
96 #define MAJOR_NR ACSI_MAJOR
98 #define CMDSET_TARG_LUN(cmd,targ,lun) \
99 do { \
100 cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \
101 cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \
102 } while(0)
104 #define START_TIMER(to) \
105 do { \
106 del_timer( &slm_timer ); \
107 slm_timer.expires = jiffies + (to); \
108 add_timer( &slm_timer ); \
109 } while(0)
111 #define STOP_TIMER() \
112 do { \
113 del_timer( &slm_timer ); \
114 } while(0)
117 static char slmreqsense_cmd[6] = { 0x03, 0, 0, 0, 0, 0 };
118 static char slmprint_cmd[6] = { 0x0a, 0, 0, 0, 0, 0 };
119 static char slminquiry_cmd[6] = { 0x12, 0, 0, 0, 0, 0x80 };
120 static char slmmsense_cmd[6] = { 0x1a, 0, 0, 0, 255, 0 };
121 #if 0
122 static char slmmselect_cmd[6] = { 0x15, 0, 0, 0, 0, 0 };
123 #endif
126 #define MAX_SLM 2
128 static struct slm {
129 unsigned target; /* target number */
130 unsigned lun; /* LUN in target controller */
131 unsigned wbusy : 1; /* output part busy */
132 unsigned rbusy : 1; /* status part busy */
133 } slm_info[MAX_SLM];
135 int N_SLM_Printers = 0;
137 /* printer buffer */
138 static unsigned char *SLMBuffer; /* start of buffer */
139 static unsigned char *BufferP; /* current position in buffer */
140 static int BufferSize; /* length of buffer for page size */
142 typedef enum { IDLE, FILLING, PRINTING } SLMSTATE;
143 static SLMSTATE SLMState;
144 static int SLMBufOwner; /* SLM# currently using the buffer */
146 /* DMA variables */
147 #ifndef SLM_CONT_CNT_REPROG
148 static unsigned long SLMCurAddr; /* current base addr of DMA chunk */
149 static unsigned long SLMEndAddr; /* expected end addr */
150 static unsigned long SLMSliceSize; /* size of one DMA chunk */
151 #endif
152 static int SLMError;
154 /* wait queues */
155 static struct wait_queue *slm_wait; /* waiting for buffer */
156 static struct wait_queue *print_wait; /* waiting for printing finished */
158 /* status codes */
159 #define SLMSTAT_OK 0x00
160 #define SLMSTAT_ORNERY 0x02
161 #define SLMSTAT_TONER 0x03
162 #define SLMSTAT_WARMUP 0x04
163 #define SLMSTAT_PAPER 0x05
164 #define SLMSTAT_DRUM 0x06
165 #define SLMSTAT_INJAM 0x07
166 #define SLMSTAT_THRJAM 0x08
167 #define SLMSTAT_OUTJAM 0x09
168 #define SLMSTAT_COVER 0x0a
169 #define SLMSTAT_FUSER 0x0b
170 #define SLMSTAT_IMAGER 0x0c
171 #define SLMSTAT_MOTOR 0x0d
172 #define SLMSTAT_VIDEO 0x0e
173 #define SLMSTAT_SYSTO 0x10
174 #define SLMSTAT_OPCODE 0x12
175 #define SLMSTAT_DEVNUM 0x15
176 #define SLMSTAT_PARAM 0x1a
177 #define SLMSTAT_ACSITO 0x1b /* driver defined */
178 #define SLMSTAT_NOTALL 0x1c /* driver defined */
180 static char *SLMErrors[] = {
181 /* 0x00 */ "OK and ready",
182 /* 0x01 */ NULL,
183 /* 0x02 */ "ornery printer",
184 /* 0x03 */ "toner empty",
185 /* 0x04 */ "warming up",
186 /* 0x05 */ "paper empty",
187 /* 0x06 */ "drum empty",
188 /* 0x07 */ "input jam",
189 /* 0x08 */ "through jam",
190 /* 0x09 */ "output jam",
191 /* 0x0a */ "cover open",
192 /* 0x0b */ "fuser malfunction",
193 /* 0x0c */ "imager malfunction",
194 /* 0x0d */ "motor malfunction",
195 /* 0x0e */ "video malfunction",
196 /* 0x0f */ NULL,
197 /* 0x10 */ "printer system timeout",
198 /* 0x11 */ NULL,
199 /* 0x12 */ "invalid operation code",
200 /* 0x13 */ NULL,
201 /* 0x14 */ NULL,
202 /* 0x15 */ "invalid device number",
203 /* 0x16 */ NULL,
204 /* 0x17 */ NULL,
205 /* 0x18 */ NULL,
206 /* 0x19 */ NULL,
207 /* 0x1a */ "invalid parameter list",
208 /* 0x1b */ "ACSI timeout",
209 /* 0x1c */ "not all printed"
212 #define N_ERRORS (sizeof(SLMErrors)/sizeof(*SLMErrors))
214 /* real (driver caused) error? */
215 #define IS_REAL_ERROR(x) (x > 0x10)
218 static struct {
219 char *name;
220 int w, h;
221 } StdPageSize[] = {
222 { "Letter", 2400, 3180 },
223 { "Legal", 2400, 4080 },
224 { "A4", 2336, 3386 },
225 { "B5", 2016, 2914 }
228 #define N_STD_SIZES (sizeof(StdPageSize)/sizeof(*StdPageSize))
230 #define SLM_BUFFER_SIZE (2336*3386/8) /* A4 for now */
231 #define SLM_DMA_AMOUNT 255 /* #sectors to program the DMA for */
233 #ifdef SLM_CONTINUOUS_DMA
234 # define SLM_DMA_INT_OFFSET 0 /* DMA goes until seccnt 0, no offs */
235 # define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */
236 # define SLM_SLICE_SIZE(w) (255*512)
237 #else
238 # define SLM_DMA_INT_OFFSET 32 /* 32 Byte ST-DMA FIFO */
239 # define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */
240 # define SLM_SLICE_SIZE(w) ((254*512)/(w/8)*(w/8))
241 #endif
243 /* calculate the number of jiffies to wait for 'n' bytes */
244 #ifdef SLM_CONT_CNT_REPROG
245 #define DMA_TIME_FOR(n) 50
246 #define DMA_STARTUP_TIME 0
247 #else
248 #define DMA_TIME_FOR(n) (n/1400-1)
249 #define DMA_STARTUP_TIME 650
250 #endif
252 /***************************** Prototypes *****************************/
254 static char *slm_errstr( int stat );
255 static int slm_getstats( char *buffer, int device );
256 static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t
257 *ppos );
258 static void start_print( int device );
259 static void slm_interrupt(int irc, void *data, struct pt_regs *fp);
260 static void slm_test_ready( unsigned long dummy );
261 static void set_dma_addr( unsigned long paddr );
262 static unsigned long get_dma_addr( void );
263 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
264 loff_t *ppos );
265 static int slm_ioctl( struct inode *inode, struct file *file, unsigned int
266 cmd, unsigned long arg );
267 static int slm_open( struct inode *inode, struct file *file );
268 static int slm_release( struct inode *inode, struct file *file );
269 static int slm_req_sense( int device );
270 static int slm_mode_sense( int device, char *buffer, int abs_flag );
271 #if 0
272 static int slm_mode_select( int device, char *buffer, int len, int
273 default_flag );
274 #endif
275 static int slm_get_pagesize( int device, int *w, int *h );
277 /************************* End of Prototypes **************************/
280 static struct timer_list slm_timer = { NULL, NULL, 0, 0, slm_test_ready };
282 static struct file_operations slm_fops = {
283 NULL, /* lseek - default */
284 slm_read, /* read - status reading */
285 slm_write, /* write - printing data write */
286 NULL, /* readdir - bad */
287 NULL, /* poll */
288 slm_ioctl, /* ioctl */
289 NULL, /* mmap */
290 slm_open, /* open */
291 NULL, /* flush */
292 slm_release, /* release */
293 NULL /* fsync */
297 /* ---------------------------------------------------------------------- */
298 /* Status Functions */
301 static char *slm_errstr( int stat )
303 { char *p;
304 static char str[22];
306 stat &= 0x1f;
307 if (stat >= 0 && stat < N_ERRORS && (p = SLMErrors[stat]))
308 return( p );
309 sprintf( str, "unknown status 0x%02x", stat );
310 return( str );
314 static int slm_getstats( char *buffer, int device )
316 { int len = 0, stat, i, w, h;
317 unsigned char buf[256];
319 stat = slm_mode_sense( device, buf, 0 );
320 if (IS_REAL_ERROR(stat))
321 return( -EIO );
323 #define SHORTDATA(i) ((buf[i] << 8) | buf[i+1])
324 #define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off")
326 w = SHORTDATA( 3 );
327 h = SHORTDATA( 1 );
329 len += sprintf( buffer+len, "Status\t\t%s\n",
330 slm_errstr( stat ) );
331 len += sprintf( buffer+len, "Page Size\t%dx%d",
332 w, h );
334 for( i = 0; i < N_STD_SIZES; ++i ) {
335 if (w == StdPageSize[i].w && h == StdPageSize[i].h)
336 break;
338 if (i < N_STD_SIZES)
339 len += sprintf( buffer+len, " (%s)", StdPageSize[i].name );
340 buffer[len++] = '\n';
342 len += sprintf( buffer+len, "Top/Left Margin\t%d/%d\n",
343 SHORTDATA( 5 ), SHORTDATA( 7 ) );
344 len += sprintf( buffer+len, "Manual Feed\t%s\n",
345 BOOLDATA( 9, 0x01 ) );
346 len += sprintf( buffer+len, "Input Select\t%d\n",
347 (buf[9] >> 1) & 7 );
348 len += sprintf( buffer+len, "Auto Select\t%s\n",
349 BOOLDATA( 9, 0x10 ) );
350 len += sprintf( buffer+len, "Prefeed Paper\t%s\n",
351 BOOLDATA( 9, 0x20 ) );
352 len += sprintf( buffer+len, "Thick Pixels\t%s\n",
353 BOOLDATA( 9, 0x40 ) );
354 len += sprintf( buffer+len, "H/V Resol.\t%d/%d dpi\n",
355 SHORTDATA( 12 ), SHORTDATA( 10 ) );
356 len += sprintf( buffer+len, "System Timeout\t%d\n",
357 buf[14] );
358 len += sprintf( buffer+len, "Scan Time\t%d\n",
359 SHORTDATA( 15 ) );
360 len += sprintf( buffer+len, "Page Count\t%d\n",
361 SHORTDATA( 17 ) );
362 len += sprintf( buffer+len, "In/Out Cap.\t%d/%d\n",
363 SHORTDATA( 19 ), SHORTDATA( 21 ) );
364 len += sprintf( buffer+len, "Stagger Output\t%s\n",
365 BOOLDATA( 23, 0x01 ) );
366 len += sprintf( buffer+len, "Output Select\t%d\n",
367 (buf[23] >> 1) & 7 );
368 len += sprintf( buffer+len, "Duplex Print\t%s\n",
369 BOOLDATA( 23, 0x10 ) );
370 len += sprintf( buffer+len, "Color Sep.\t%s\n",
371 BOOLDATA( 23, 0x20 ) );
373 return( len );
377 static ssize_t slm_read( struct file *file, char *buf, size_t count,
378 loff_t *ppos )
381 struct inode *node = file->f_dentry->d_inode;
382 unsigned long page;
383 int length;
384 int end;
386 if (count < 0)
387 return( -EINVAL );
388 if (!(page = __get_free_page( GFP_KERNEL )))
389 return( -ENOMEM );
391 length = slm_getstats( (char *)page, MINOR(node->i_rdev) );
392 if (length < 0) {
393 free_page( page );
394 return( length );
396 if (file->f_pos >= length) {
397 free_page( page );
398 return( 0 );
400 if (count + file->f_pos > length)
401 count = length - file->f_pos;
402 end = count + file->f_pos;
403 copy_to_user( buf, (char *)page + file->f_pos, count );
404 free_page( page );
405 file->f_pos = end;
406 return( count );
410 /* ---------------------------------------------------------------------- */
411 /* Printing */
414 static void start_print( int device )
416 { struct slm *sip = &slm_info[device];
417 unsigned char *cmd;
418 unsigned long paddr;
419 int i;
421 stdma_lock( slm_interrupt, NULL );
423 CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun );
424 cmd = slmprint_cmd;
425 paddr = VTOP( SLMBuffer );
426 dma_cache_maintenance( paddr, VTOP(BufferP)-paddr, 1 );
427 DISABLE_IRQ();
429 /* Low on A1 */
430 dma_wd.dma_mode_status = 0x88;
431 MFPDELAY();
433 /* send the command bytes except the last */
434 for( i = 0; i < 5; ++i ) {
435 DMA_LONG_WRITE( *cmd++, 0x8a );
436 udelay(20);
437 if (!acsi_wait_for_IRQ( HZ/2 )) {
438 SLMError = 1;
439 return; /* timeout */
442 /* last command byte */
443 DMA_LONG_WRITE( *cmd++, 0x82 );
444 MFPDELAY();
445 /* set DMA address */
446 set_dma_addr( paddr );
447 /* program DMA for write and select sector counter reg */
448 dma_wd.dma_mode_status = 0x192;
449 MFPDELAY();
450 /* program for 255*512 bytes and start DMA */
451 DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
453 #ifndef SLM_CONT_CNT_REPROG
454 SLMCurAddr = paddr;
455 SLMEndAddr = paddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
456 #endif
457 START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize ));
458 #if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG)
459 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
460 SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
461 #endif
463 ENABLE_IRQ();
467 /* Only called when an error happened or at the end of a page */
469 static void slm_interrupt(int irc, void *data, struct pt_regs *fp)
471 { unsigned long addr;
472 int stat;
474 STOP_TIMER();
475 addr = get_dma_addr();
476 stat = acsi_getstatus();
477 SLMError = (stat < 0) ? SLMSTAT_ACSITO :
478 (addr < VTOP(BufferP)) ? SLMSTAT_NOTALL :
479 stat;
481 dma_wd.dma_mode_status = 0x80;
482 MFPDELAY();
483 #ifdef DEBUG
484 printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr, SLMError );
485 #endif
487 wake_up( &print_wait );
488 stdma_release();
489 ENABLE_IRQ();
493 static void slm_test_ready( unsigned long dummy )
496 #ifdef SLM_CONT_CNT_REPROG
497 /* program for 255*512 bytes again */
498 dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
499 START_TIMER( DMA_TIME_FOR(0) );
500 #ifdef DEBUG
501 printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
502 DMA_TIME_FOR(0), get_dma_addr() );
503 #endif
505 #else /* !SLM_CONT_CNT_REPROG */
507 unsigned long flags, addr;
508 int d, ti;
509 #ifdef DEBUG
510 struct timeval start_tm, end_tm;
511 int did_wait = 0;
512 #endif
514 save_flags(flags);
515 cli();
517 addr = get_dma_addr();
518 if ((d = SLMEndAddr - addr) > 0) {
519 restore_flags(flags);
521 /* slice not yet finished, decide whether to start another timer or to
522 * busy-wait */
523 ti = DMA_TIME_FOR( d );
524 if (ti > 0) {
525 #ifdef DEBUG
526 printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
527 ti, d );
528 #endif
529 START_TIMER( ti );
530 return;
532 /* wait for desired end address to be reached */
533 #ifdef DEBUG
534 do_gettimeofday( &start_tm );
535 did_wait = 1;
536 #endif
537 cli();
538 while( get_dma_addr() < SLMEndAddr )
539 barrier();
542 /* slice finished, start next one */
543 SLMCurAddr += SLMSliceSize;
545 #ifdef SLM_CONTINUOUS_DMA
546 /* program for 255*512 bytes again */
547 dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
548 #else
549 /* set DMA address;
550 * add 2 bytes for the ones in the SLM controller FIFO! */
551 set_dma_addr( SLMCurAddr + 2 );
552 /* toggle DMA to write and select sector counter reg */
553 dma_wd.dma_mode_status = 0x92;
554 MFPDELAY();
555 dma_wd.dma_mode_status = 0x192;
556 MFPDELAY();
557 /* program for 255*512 bytes and start DMA */
558 DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
559 #endif
561 restore_flags(flags);
563 #ifdef DEBUG
564 if (did_wait) {
565 int ms;
566 do_gettimeofday( &end_tm );
567 ms = (end_tm.tv_sec*1000000+end_tm.tv_usec) -
568 (start_tm.tv_sec*1000000+start_tm.tv_usec);
569 printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n",
570 ms/1000, ms%1000, d );
572 else
573 printk( "SLM: didn't wait (!)\n" );
574 #endif
576 if ((unsigned char *)PTOV( SLMCurAddr + SLMSliceSize ) >= BufferP) {
577 /* will be last slice, no timer necessary */
578 #ifdef DEBUG
579 printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
580 SLMCurAddr, SLMEndAddr );
581 #endif
583 else {
584 /* not last slice */
585 SLMEndAddr = SLMCurAddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
586 START_TIMER( DMA_TIME_FOR( SLMSliceSize ));
587 #ifdef DEBUG
588 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
589 SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
590 #endif
592 #endif /* SLM_CONT_CNT_REPROG */
596 static void set_dma_addr( unsigned long paddr )
598 { unsigned long flags;
600 save_flags(flags);
601 cli();
602 dma_wd.dma_lo = (unsigned char)paddr;
603 paddr >>= 8;
604 MFPDELAY();
605 dma_wd.dma_md = (unsigned char)paddr;
606 paddr >>= 8;
607 MFPDELAY();
608 if (ATARIHW_PRESENT( EXTD_DMA ))
609 st_dma_ext_dmahi = (unsigned short)paddr;
610 else
611 dma_wd.dma_hi = (unsigned char)paddr;
612 MFPDELAY();
613 restore_flags(flags);
617 static unsigned long get_dma_addr( void )
619 { unsigned long addr;
621 addr = dma_wd.dma_lo & 0xff;
622 MFPDELAY();
623 addr |= (dma_wd.dma_md & 0xff) << 8;
624 MFPDELAY();
625 addr |= (dma_wd.dma_hi & 0xff) << 16;
626 MFPDELAY();
628 return( addr );
632 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
633 loff_t *ppos )
636 struct inode *node = file->f_dentry->d_inode;
637 int device = MINOR( node->i_rdev );
638 int n, filled, w, h;
640 while( SLMState == PRINTING ||
641 (SLMState == FILLING && SLMBufOwner != device) ) {
642 interruptible_sleep_on( &slm_wait );
643 if (signal_pending(current))
644 return( -ERESTARTSYS );
646 if (SLMState == IDLE) {
647 /* first data of page: get current page size */
648 if (slm_get_pagesize( device, &w, &h ))
649 return( -EIO );
650 BufferSize = w*h/8;
651 if (BufferSize > SLM_BUFFER_SIZE)
652 return( -ENOMEM );
654 SLMState = FILLING;
655 SLMBufOwner = device;
658 n = count;
659 filled = BufferP - SLMBuffer;
660 if (filled + n > BufferSize)
661 n = BufferSize - filled;
663 copy_from_user( BufferP, buf, n );
664 BufferP += n;
665 filled += n;
667 if (filled == BufferSize) {
668 /* Check the paper size again! The user may have switched it in the
669 * time between starting the data and finishing them. Would end up in
670 * a trashy page... */
671 if (slm_get_pagesize( device, &w, &h ))
672 return( -EIO );
673 if (BufferSize != w*h/8) {
674 printk( KERN_NOTICE "slm%d: page size changed while printing\n",
675 device );
676 return( -EAGAIN );
679 SLMState = PRINTING;
680 /* choose a slice size that is a multiple of the line size */
681 #ifndef SLM_CONT_CNT_REPROG
682 SLMSliceSize = SLM_SLICE_SIZE(w);
683 #endif
685 start_print( device );
686 sleep_on( &print_wait );
687 if (SLMError && IS_REAL_ERROR(SLMError)) {
688 printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) );
689 n = -EIO;
692 SLMState = IDLE;
693 BufferP = SLMBuffer;
694 wake_up_interruptible( &slm_wait );
697 return( n );
701 /* ---------------------------------------------------------------------- */
702 /* ioctl Functions */
705 static int slm_ioctl( struct inode *inode, struct file *file,
706 unsigned int cmd, unsigned long arg )
708 { int device = MINOR( inode->i_rdev ), err;
710 /* I can think of setting:
711 * - manual feed
712 * - paper format
713 * - copy count
714 * - ...
715 * but haven't implemented that yet :-)
716 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
718 switch( cmd ) {
720 case SLMIORESET: /* reset buffer, i.e. empty the buffer */
721 if (!(file->f_mode & 2))
722 return( -EINVAL );
723 if (SLMState == PRINTING)
724 return( -EBUSY );
725 SLMState = IDLE;
726 BufferP = SLMBuffer;
727 wake_up_interruptible( &slm_wait );
728 return( 0 );
730 case SLMIOGSTAT: { /* get status */
731 int stat;
732 char *str;
734 stat = slm_req_sense( device );
735 if (arg) {
736 str = slm_errstr( stat );
737 if (put_user(stat,
738 (long *)&((struct SLM_status *)arg)->stat))
739 return -EFAULT;
740 copy_to_user( ((struct SLM_status *)arg)->str, str,
741 strlen(str) + 1 );
743 return( stat );
746 case SLMIOGPSIZE: { /* get paper size */
747 int w, h;
749 err = verify_area( VERIFY_WRITE, (long *)arg,
750 sizeof(struct SLM_paper_size) );
751 if (err) return( err );
753 if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
755 if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
756 return -EFAULT;
757 if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height))
758 return -EFAULT;
759 return( 0 );
762 case SLMIOGMFEED: /* get manual feed */
763 return( -EINVAL );
765 case SLMIOSPSIZE: /* set paper size */
766 return( -EINVAL );
768 case SLMIOSMFEED: /* set manual feed */
769 return( -EINVAL );
772 return( -EINVAL );
776 /* ---------------------------------------------------------------------- */
777 /* Opening and Closing */
780 static int slm_open( struct inode *inode, struct file *file )
782 { int device;
783 struct slm *sip;
785 device = MINOR(inode->i_rdev);
786 if (device >= N_SLM_Printers)
787 return( -ENXIO );
788 sip = &slm_info[device];
790 if (file->f_mode & 2) {
791 /* open for writing is exclusive */
792 if (sip->wbusy)
793 return( -EBUSY );
794 sip->wbusy = 1;
796 if (file->f_mode & 1) {
797 /* open for writing is exclusive */
798 if (sip->rbusy)
799 return( -EBUSY );
800 sip->rbusy = 1;
803 return( 0 );
807 static int slm_release( struct inode *inode, struct file *file )
809 { int device;
810 struct slm *sip;
812 device = MINOR(inode->i_rdev);
813 sip = &slm_info[device];
815 if (file->f_mode & 2)
816 sip->wbusy = 0;
817 if (file->f_mode & 1)
818 sip->rbusy = 0;
820 return( 0 );
824 /* ---------------------------------------------------------------------- */
825 /* ACSI Primitives for the SLM */
828 static int slm_req_sense( int device )
830 { int stat, rv;
831 struct slm *sip = &slm_info[device];
833 stdma_lock( NULL, NULL );
835 CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun );
836 if (!acsicmd_nodma( slmreqsense_cmd, 0 ) ||
837 (stat = acsi_getstatus()) < 0)
838 rv = SLMSTAT_ACSITO;
839 else
840 rv = stat & 0x1f;
842 ENABLE_IRQ();
843 stdma_release();
844 return( rv );
848 static int slm_mode_sense( int device, char *buffer, int abs_flag )
850 { unsigned char stat, len;
851 int rv = 0;
852 struct slm *sip = &slm_info[device];
854 stdma_lock( NULL, NULL );
856 CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun );
857 slmmsense_cmd[5] = abs_flag ? 0x80 : 0;
858 if (!acsicmd_nodma( slmmsense_cmd, 0 )) {
859 rv = SLMSTAT_ACSITO;
860 goto the_end;
863 if (!acsi_extstatus( &stat, 1 )) {
864 acsi_end_extstatus();
865 rv = SLMSTAT_ACSITO;
866 goto the_end;
869 if (!acsi_extstatus( &len, 1 )) {
870 acsi_end_extstatus();
871 rv = SLMSTAT_ACSITO;
872 goto the_end;
874 buffer[0] = len;
875 if (!acsi_extstatus( buffer+1, len )) {
876 acsi_end_extstatus();
877 rv = SLMSTAT_ACSITO;
878 goto the_end;
881 acsi_end_extstatus();
882 rv = stat & 0x1f;
884 the_end:
885 ENABLE_IRQ();
886 stdma_release();
887 return( rv );
891 #if 0
892 /* currently unused */
893 static int slm_mode_select( int device, char *buffer, int len,
894 int default_flag )
896 { int stat, rv;
897 struct slm *sip = &slm_info[device];
899 stdma_lock( NULL, NULL );
901 CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun );
902 slmmselect_cmd[5] = default_flag ? 0x80 : 0;
903 if (!acsicmd_nodma( slmmselect_cmd, 0 )) {
904 rv = SLMSTAT_ACSITO;
905 goto the_end;
908 if (!default_flag) {
909 unsigned char c = len;
910 if (!acsi_extcmd( &c, 1 )) {
911 rv = SLMSTAT_ACSITO;
912 goto the_end;
914 if (!acsi_extcmd( buffer, len )) {
915 rv = SLMSTAT_ACSITO;
916 goto the_end;
920 stat = acsi_getstatus();
921 rv = (stat < 0 ? SLMSTAT_ACSITO : stat);
923 the_end:
924 ENABLE_IRQ();
925 stdma_release();
926 return( rv );
928 #endif
931 static int slm_get_pagesize( int device, int *w, int *h )
933 { char buf[256];
934 int stat;
936 stat = slm_mode_sense( device, buf, 0 );
937 ENABLE_IRQ();
938 stdma_release();
940 if (stat != SLMSTAT_OK)
941 return( -EIO );
943 *w = (buf[3] << 8) | buf[4];
944 *h = (buf[1] << 8) | buf[2];
945 return( 0 );
949 /* ---------------------------------------------------------------------- */
950 /* Initialization */
953 int attach_slm( int target, int lun )
955 { static int did_register = 0;
956 int len;
958 if (N_SLM_Printers >= MAX_SLM) {
959 printk( KERN_WARNING "Too much SLMs\n" );
960 return( 0 );
963 /* do an INQUIRY */
964 udelay(100);
965 CMDSET_TARG_LUN( slminquiry_cmd, target, lun );
966 if (!acsicmd_nodma( slminquiry_cmd, 0 )) {
967 inq_timeout:
968 printk( KERN_ERR "SLM inquiry command timed out.\n" );
969 inq_fail:
970 acsi_end_extstatus();
971 return( 0 );
973 /* read status and header of return data */
974 if (!acsi_extstatus( SLMBuffer, 6 ))
975 goto inq_timeout;
977 if (SLMBuffer[1] != 2) { /* device type == printer? */
978 printk( KERN_ERR "SLM inquiry returned device type != printer\n" );
979 goto inq_fail;
981 len = SLMBuffer[5];
983 /* read id string */
984 if (!acsi_extstatus( SLMBuffer, len ))
985 goto inq_timeout;
986 acsi_end_extstatus();
987 SLMBuffer[len] = 0;
989 if (!did_register) {
990 did_register = 1;
993 slm_info[N_SLM_Printers].target = target;
994 slm_info[N_SLM_Printers].lun = lun;
995 slm_info[N_SLM_Printers].wbusy = 0;
996 slm_info[N_SLM_Printers].rbusy = 0;
998 printk( KERN_INFO " Printer: %s\n", SLMBuffer );
999 printk( KERN_INFO "Detected slm%d at id %d lun %d\n",
1000 N_SLM_Printers, target, lun );
1001 N_SLM_Printers++;
1002 return( 1 );
1006 int slm_init( void )
1009 if (register_chrdev( MAJOR_NR, "slm", &slm_fops )) {
1010 printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", MAJOR_NR );
1011 return -EBUSY;
1014 if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, NULL, "SLM" ))) {
1015 printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" );
1016 unregister_chrdev( MAJOR_NR, "slm" );
1017 return -ENOMEM;
1019 BufferP = SLMBuffer;
1020 SLMState = IDLE;
1022 return 0;
1025 #ifdef MODULE
1027 /* from acsi.c */
1028 void acsi_attach_SLMs( int (*attach_func)( int, int ) );
1030 int init_module(void)
1032 int err;
1034 if ((err = slm_init()))
1035 return( err );
1036 /* This calls attach_slm() for every target/lun where acsi.c detected a
1037 * printer */
1038 acsi_attach_SLMs( attach_slm );
1039 return( 0 );
1042 void cleanup_module(void)
1044 if (unregister_chrdev( MAJOR_NR, "slm" ) != 0)
1045 printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
1046 atari_stram_free( SLMBuffer );
1048 #endif