Import 2.3.9pre5
[davej-history.git] / drivers / block / acsi_slm.c
blobb341c39c4692315ddf41a02e04def02586920c61
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) mod_timer(&slm_timer, jiffies + (to))
105 #define STOP_TIMER() del_timer(&slm_timer)
108 static char slmreqsense_cmd[6] = { 0x03, 0, 0, 0, 0, 0 };
109 static char slmprint_cmd[6] = { 0x0a, 0, 0, 0, 0, 0 };
110 static char slminquiry_cmd[6] = { 0x12, 0, 0, 0, 0, 0x80 };
111 static char slmmsense_cmd[6] = { 0x1a, 0, 0, 0, 255, 0 };
112 #if 0
113 static char slmmselect_cmd[6] = { 0x15, 0, 0, 0, 0, 0 };
114 #endif
117 #define MAX_SLM 2
119 static struct slm {
120 unsigned target; /* target number */
121 unsigned lun; /* LUN in target controller */
122 unsigned wbusy : 1; /* output part busy */
123 unsigned rbusy : 1; /* status part busy */
124 } slm_info[MAX_SLM];
126 int N_SLM_Printers = 0;
128 /* printer buffer */
129 static unsigned char *SLMBuffer; /* start of buffer */
130 static unsigned char *BufferP; /* current position in buffer */
131 static int BufferSize; /* length of buffer for page size */
133 typedef enum { IDLE, FILLING, PRINTING } SLMSTATE;
134 static SLMSTATE SLMState;
135 static int SLMBufOwner; /* SLM# currently using the buffer */
137 /* DMA variables */
138 #ifndef SLM_CONT_CNT_REPROG
139 static unsigned long SLMCurAddr; /* current base addr of DMA chunk */
140 static unsigned long SLMEndAddr; /* expected end addr */
141 static unsigned long SLMSliceSize; /* size of one DMA chunk */
142 #endif
143 static int SLMError;
145 /* wait queues */
146 static DECLARE_WAIT_QUEUE_HEAD(slm_wait); /* waiting for buffer */
147 static DECLARE_WAIT_QUEUE_HEAD(print_wait); /* waiting for printing finished */
149 /* status codes */
150 #define SLMSTAT_OK 0x00
151 #define SLMSTAT_ORNERY 0x02
152 #define SLMSTAT_TONER 0x03
153 #define SLMSTAT_WARMUP 0x04
154 #define SLMSTAT_PAPER 0x05
155 #define SLMSTAT_DRUM 0x06
156 #define SLMSTAT_INJAM 0x07
157 #define SLMSTAT_THRJAM 0x08
158 #define SLMSTAT_OUTJAM 0x09
159 #define SLMSTAT_COVER 0x0a
160 #define SLMSTAT_FUSER 0x0b
161 #define SLMSTAT_IMAGER 0x0c
162 #define SLMSTAT_MOTOR 0x0d
163 #define SLMSTAT_VIDEO 0x0e
164 #define SLMSTAT_SYSTO 0x10
165 #define SLMSTAT_OPCODE 0x12
166 #define SLMSTAT_DEVNUM 0x15
167 #define SLMSTAT_PARAM 0x1a
168 #define SLMSTAT_ACSITO 0x1b /* driver defined */
169 #define SLMSTAT_NOTALL 0x1c /* driver defined */
171 static char *SLMErrors[] = {
172 /* 0x00 */ "OK and ready",
173 /* 0x01 */ NULL,
174 /* 0x02 */ "ornery printer",
175 /* 0x03 */ "toner empty",
176 /* 0x04 */ "warming up",
177 /* 0x05 */ "paper empty",
178 /* 0x06 */ "drum empty",
179 /* 0x07 */ "input jam",
180 /* 0x08 */ "through jam",
181 /* 0x09 */ "output jam",
182 /* 0x0a */ "cover open",
183 /* 0x0b */ "fuser malfunction",
184 /* 0x0c */ "imager malfunction",
185 /* 0x0d */ "motor malfunction",
186 /* 0x0e */ "video malfunction",
187 /* 0x0f */ NULL,
188 /* 0x10 */ "printer system timeout",
189 /* 0x11 */ NULL,
190 /* 0x12 */ "invalid operation code",
191 /* 0x13 */ NULL,
192 /* 0x14 */ NULL,
193 /* 0x15 */ "invalid device number",
194 /* 0x16 */ NULL,
195 /* 0x17 */ NULL,
196 /* 0x18 */ NULL,
197 /* 0x19 */ NULL,
198 /* 0x1a */ "invalid parameter list",
199 /* 0x1b */ "ACSI timeout",
200 /* 0x1c */ "not all printed"
203 #define N_ERRORS (sizeof(SLMErrors)/sizeof(*SLMErrors))
205 /* real (driver caused) error? */
206 #define IS_REAL_ERROR(x) (x > 0x10)
209 static struct {
210 char *name;
211 int w, h;
212 } StdPageSize[] = {
213 { "Letter", 2400, 3180 },
214 { "Legal", 2400, 4080 },
215 { "A4", 2336, 3386 },
216 { "B5", 2016, 2914 }
219 #define N_STD_SIZES (sizeof(StdPageSize)/sizeof(*StdPageSize))
221 #define SLM_BUFFER_SIZE (2336*3386/8) /* A4 for now */
222 #define SLM_DMA_AMOUNT 255 /* #sectors to program the DMA for */
224 #ifdef SLM_CONTINUOUS_DMA
225 # define SLM_DMA_INT_OFFSET 0 /* DMA goes until seccnt 0, no offs */
226 # define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */
227 # define SLM_SLICE_SIZE(w) (255*512)
228 #else
229 # define SLM_DMA_INT_OFFSET 32 /* 32 Byte ST-DMA FIFO */
230 # define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */
231 # define SLM_SLICE_SIZE(w) ((254*512)/(w/8)*(w/8))
232 #endif
234 /* calculate the number of jiffies to wait for 'n' bytes */
235 #ifdef SLM_CONT_CNT_REPROG
236 #define DMA_TIME_FOR(n) 50
237 #define DMA_STARTUP_TIME 0
238 #else
239 #define DMA_TIME_FOR(n) (n/1400-1)
240 #define DMA_STARTUP_TIME 650
241 #endif
243 /***************************** Prototypes *****************************/
245 static char *slm_errstr( int stat );
246 static int slm_getstats( char *buffer, int device );
247 static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t
248 *ppos );
249 static void start_print( int device );
250 static void slm_interrupt(int irc, void *data, struct pt_regs *fp);
251 static void slm_test_ready( unsigned long dummy );
252 static void set_dma_addr( unsigned long paddr );
253 static unsigned long get_dma_addr( void );
254 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
255 loff_t *ppos );
256 static int slm_ioctl( struct inode *inode, struct file *file, unsigned int
257 cmd, unsigned long arg );
258 static int slm_open( struct inode *inode, struct file *file );
259 static int slm_release( struct inode *inode, struct file *file );
260 static int slm_req_sense( int device );
261 static int slm_mode_sense( int device, char *buffer, int abs_flag );
262 #if 0
263 static int slm_mode_select( int device, char *buffer, int len, int
264 default_flag );
265 #endif
266 static int slm_get_pagesize( int device, int *w, int *h );
268 /************************* End of Prototypes **************************/
271 static struct timer_list slm_timer = { NULL, NULL, 0, 0, slm_test_ready };
273 static struct file_operations slm_fops = {
274 NULL, /* lseek - default */
275 slm_read, /* read - status reading */
276 slm_write, /* write - printing data write */
277 NULL, /* readdir - bad */
278 NULL, /* poll */
279 slm_ioctl, /* ioctl */
280 NULL, /* mmap */
281 slm_open, /* open */
282 NULL, /* flush */
283 slm_release, /* release */
284 NULL /* fsync */
288 /* ---------------------------------------------------------------------- */
289 /* Status Functions */
292 static char *slm_errstr( int stat )
294 { char *p;
295 static char str[22];
297 stat &= 0x1f;
298 if (stat >= 0 && stat < N_ERRORS && (p = SLMErrors[stat]))
299 return( p );
300 sprintf( str, "unknown status 0x%02x", stat );
301 return( str );
305 static int slm_getstats( char *buffer, int device )
307 { int len = 0, stat, i, w, h;
308 unsigned char buf[256];
310 stat = slm_mode_sense( device, buf, 0 );
311 if (IS_REAL_ERROR(stat))
312 return( -EIO );
314 #define SHORTDATA(i) ((buf[i] << 8) | buf[i+1])
315 #define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off")
317 w = SHORTDATA( 3 );
318 h = SHORTDATA( 1 );
320 len += sprintf( buffer+len, "Status\t\t%s\n",
321 slm_errstr( stat ) );
322 len += sprintf( buffer+len, "Page Size\t%dx%d",
323 w, h );
325 for( i = 0; i < N_STD_SIZES; ++i ) {
326 if (w == StdPageSize[i].w && h == StdPageSize[i].h)
327 break;
329 if (i < N_STD_SIZES)
330 len += sprintf( buffer+len, " (%s)", StdPageSize[i].name );
331 buffer[len++] = '\n';
333 len += sprintf( buffer+len, "Top/Left Margin\t%d/%d\n",
334 SHORTDATA( 5 ), SHORTDATA( 7 ) );
335 len += sprintf( buffer+len, "Manual Feed\t%s\n",
336 BOOLDATA( 9, 0x01 ) );
337 len += sprintf( buffer+len, "Input Select\t%d\n",
338 (buf[9] >> 1) & 7 );
339 len += sprintf( buffer+len, "Auto Select\t%s\n",
340 BOOLDATA( 9, 0x10 ) );
341 len += sprintf( buffer+len, "Prefeed Paper\t%s\n",
342 BOOLDATA( 9, 0x20 ) );
343 len += sprintf( buffer+len, "Thick Pixels\t%s\n",
344 BOOLDATA( 9, 0x40 ) );
345 len += sprintf( buffer+len, "H/V Resol.\t%d/%d dpi\n",
346 SHORTDATA( 12 ), SHORTDATA( 10 ) );
347 len += sprintf( buffer+len, "System Timeout\t%d\n",
348 buf[14] );
349 len += sprintf( buffer+len, "Scan Time\t%d\n",
350 SHORTDATA( 15 ) );
351 len += sprintf( buffer+len, "Page Count\t%d\n",
352 SHORTDATA( 17 ) );
353 len += sprintf( buffer+len, "In/Out Cap.\t%d/%d\n",
354 SHORTDATA( 19 ), SHORTDATA( 21 ) );
355 len += sprintf( buffer+len, "Stagger Output\t%s\n",
356 BOOLDATA( 23, 0x01 ) );
357 len += sprintf( buffer+len, "Output Select\t%d\n",
358 (buf[23] >> 1) & 7 );
359 len += sprintf( buffer+len, "Duplex Print\t%s\n",
360 BOOLDATA( 23, 0x10 ) );
361 len += sprintf( buffer+len, "Color Sep.\t%s\n",
362 BOOLDATA( 23, 0x20 ) );
364 return( len );
368 static ssize_t slm_read( struct file *file, char *buf, size_t count,
369 loff_t *ppos )
372 struct inode *node = file->f_dentry->d_inode;
373 unsigned long page;
374 int length;
375 int end;
377 if (count < 0)
378 return( -EINVAL );
379 if (!(page = __get_free_page( GFP_KERNEL )))
380 return( -ENOMEM );
382 length = slm_getstats( (char *)page, MINOR(node->i_rdev) );
383 if (length < 0) {
384 free_page( page );
385 return( length );
387 if (file->f_pos >= length) {
388 free_page( page );
389 return( 0 );
391 if (count + file->f_pos > length)
392 count = length - file->f_pos;
393 end = count + file->f_pos;
394 copy_to_user( buf, (char *)page + file->f_pos, count );
395 free_page( page );
396 file->f_pos = end;
397 return( count );
401 /* ---------------------------------------------------------------------- */
402 /* Printing */
405 static void start_print( int device )
407 { struct slm *sip = &slm_info[device];
408 unsigned char *cmd;
409 unsigned long paddr;
410 int i;
412 stdma_lock( slm_interrupt, NULL );
414 CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun );
415 cmd = slmprint_cmd;
416 paddr = VTOP( SLMBuffer );
417 dma_cache_maintenance( paddr, VTOP(BufferP)-paddr, 1 );
418 DISABLE_IRQ();
420 /* Low on A1 */
421 dma_wd.dma_mode_status = 0x88;
422 MFPDELAY();
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 */
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 );
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
454 ENABLE_IRQ();
458 /* Only called when an error happened or at the end of a page */
460 static void slm_interrupt(int irc, void *data, struct pt_regs *fp)
462 { unsigned long addr;
463 int stat;
465 STOP_TIMER();
466 addr = get_dma_addr();
467 stat = acsi_getstatus();
468 SLMError = (stat < 0) ? SLMSTAT_ACSITO :
469 (addr < VTOP(BufferP)) ? SLMSTAT_NOTALL :
470 stat;
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
478 wake_up( &print_wait );
479 stdma_release();
480 ENABLE_IRQ();
484 static void slm_test_ready( unsigned long dummy )
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
496 #else /* !SLM_CONT_CNT_REPROG */
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
505 save_flags(flags);
506 cli();
508 addr = get_dma_addr();
509 if ((d = SLMEndAddr - addr) > 0) {
510 restore_flags(flags);
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;
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();
533 /* slice finished, start next one */
534 SLMCurAddr += SLMSliceSize;
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
552 restore_flags(flags);
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 );
563 else
564 printk( "SLM: didn't wait (!)\n" );
565 #endif
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
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
583 #endif /* SLM_CONT_CNT_REPROG */
587 static void set_dma_addr( unsigned long paddr )
589 { unsigned long flags;
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);
608 static unsigned long get_dma_addr( void )
610 { unsigned long addr;
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();
619 return( addr );
623 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
624 loff_t *ppos )
627 struct inode *node = file->f_dentry->d_inode;
628 int device = MINOR( node->i_rdev );
629 int n, filled, w, h;
631 while( SLMState == PRINTING ||
632 (SLMState == FILLING && SLMBufOwner != device) ) {
633 interruptible_sleep_on( &slm_wait );
634 if (signal_pending(current))
635 return( -ERESTARTSYS );
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 );
645 SLMState = FILLING;
646 SLMBufOwner = device;
649 n = count;
650 filled = BufferP - SLMBuffer;
651 if (filled + n > BufferSize)
652 n = BufferSize - filled;
654 copy_from_user( BufferP, buf, n );
655 BufferP += n;
656 filled += n;
658 if (filled == BufferSize) {
659 /* Check the paper size again! The user may have switched it in the
660 * time between starting the data and finishing them. Would end up in
661 * a trashy page... */
662 if (slm_get_pagesize( device, &w, &h ))
663 return( -EIO );
664 if (BufferSize != w*h/8) {
665 printk( KERN_NOTICE "slm%d: page size changed while printing\n",
666 device );
667 return( -EAGAIN );
670 SLMState = PRINTING;
671 /* choose a slice size that is a multiple of the line size */
672 #ifndef SLM_CONT_CNT_REPROG
673 SLMSliceSize = SLM_SLICE_SIZE(w);
674 #endif
676 start_print( device );
677 sleep_on( &print_wait );
678 if (SLMError && IS_REAL_ERROR(SLMError)) {
679 printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) );
680 n = -EIO;
683 SLMState = IDLE;
684 BufferP = SLMBuffer;
685 wake_up_interruptible( &slm_wait );
688 return( n );
692 /* ---------------------------------------------------------------------- */
693 /* ioctl Functions */
696 static int slm_ioctl( struct inode *inode, struct file *file,
697 unsigned int cmd, unsigned long arg )
699 { int device = MINOR( inode->i_rdev ), err;
701 /* I can think of setting:
702 * - manual feed
703 * - paper format
704 * - copy count
705 * - ...
706 * but haven't implemented that yet :-)
707 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
709 switch( cmd ) {
711 case SLMIORESET: /* reset buffer, i.e. empty the buffer */
712 if (!(file->f_mode & 2))
713 return( -EINVAL );
714 if (SLMState == PRINTING)
715 return( -EBUSY );
716 SLMState = IDLE;
717 BufferP = SLMBuffer;
718 wake_up_interruptible( &slm_wait );
719 return( 0 );
721 case SLMIOGSTAT: { /* get status */
722 int stat;
723 char *str;
725 stat = slm_req_sense( device );
726 if (arg) {
727 str = slm_errstr( stat );
728 if (put_user(stat,
729 (long *)&((struct SLM_status *)arg)->stat))
730 return -EFAULT;
731 copy_to_user( ((struct SLM_status *)arg)->str, str,
732 strlen(str) + 1 );
734 return( stat );
737 case SLMIOGPSIZE: { /* get paper size */
738 int w, h;
740 err = verify_area( VERIFY_WRITE, (long *)arg,
741 sizeof(struct SLM_paper_size) );
742 if (err) return( err );
744 if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
746 if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
747 return -EFAULT;
748 if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height))
749 return -EFAULT;
750 return( 0 );
753 case SLMIOGMFEED: /* get manual feed */
754 return( -EINVAL );
756 case SLMIOSPSIZE: /* set paper size */
757 return( -EINVAL );
759 case SLMIOSMFEED: /* set manual feed */
760 return( -EINVAL );
763 return( -EINVAL );
767 /* ---------------------------------------------------------------------- */
768 /* Opening and Closing */
771 static int slm_open( struct inode *inode, struct file *file )
773 { int device;
774 struct slm *sip;
776 device = MINOR(inode->i_rdev);
777 if (device >= N_SLM_Printers)
778 return( -ENXIO );
779 sip = &slm_info[device];
781 if (file->f_mode & 2) {
782 /* open for writing is exclusive */
783 if (sip->wbusy)
784 return( -EBUSY );
785 sip->wbusy = 1;
787 if (file->f_mode & 1) {
788 /* open for writing is exclusive */
789 if (sip->rbusy)
790 return( -EBUSY );
791 sip->rbusy = 1;
794 return( 0 );
798 static int slm_release( struct inode *inode, struct file *file )
800 { int device;
801 struct slm *sip;
803 device = MINOR(inode->i_rdev);
804 sip = &slm_info[device];
806 if (file->f_mode & 2)
807 sip->wbusy = 0;
808 if (file->f_mode & 1)
809 sip->rbusy = 0;
811 return( 0 );
815 /* ---------------------------------------------------------------------- */
816 /* ACSI Primitives for the SLM */
819 static int slm_req_sense( int device )
821 { int stat, rv;
822 struct slm *sip = &slm_info[device];
824 stdma_lock( NULL, NULL );
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;
833 ENABLE_IRQ();
834 stdma_release();
835 return( rv );
839 static int slm_mode_sense( int device, char *buffer, int abs_flag )
841 { unsigned char stat, len;
842 int rv = 0;
843 struct slm *sip = &slm_info[device];
845 stdma_lock( NULL, NULL );
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;
854 if (!acsi_extstatus( &stat, 1 )) {
855 acsi_end_extstatus();
856 rv = SLMSTAT_ACSITO;
857 goto the_end;
860 if (!acsi_extstatus( &len, 1 )) {
861 acsi_end_extstatus();
862 rv = SLMSTAT_ACSITO;
863 goto the_end;
865 buffer[0] = len;
866 if (!acsi_extstatus( buffer+1, len )) {
867 acsi_end_extstatus();
868 rv = SLMSTAT_ACSITO;
869 goto the_end;
872 acsi_end_extstatus();
873 rv = stat & 0x1f;
875 the_end:
876 ENABLE_IRQ();
877 stdma_release();
878 return( rv );
882 #if 0
883 /* currently unused */
884 static int slm_mode_select( int device, char *buffer, int len,
885 int default_flag )
887 { int stat, rv;
888 struct slm *sip = &slm_info[device];
890 stdma_lock( NULL, NULL );
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;
899 if (!default_flag) {
900 unsigned char c = len;
901 if (!acsi_extcmd( &c, 1 )) {
902 rv = SLMSTAT_ACSITO;
903 goto the_end;
905 if (!acsi_extcmd( buffer, len )) {
906 rv = SLMSTAT_ACSITO;
907 goto the_end;
911 stat = acsi_getstatus();
912 rv = (stat < 0 ? SLMSTAT_ACSITO : stat);
914 the_end:
915 ENABLE_IRQ();
916 stdma_release();
917 return( rv );
919 #endif
922 static int slm_get_pagesize( int device, int *w, int *h )
924 { char buf[256];
925 int stat;
927 stat = slm_mode_sense( device, buf, 0 );
928 ENABLE_IRQ();
929 stdma_release();
931 if (stat != SLMSTAT_OK)
932 return( -EIO );
934 *w = (buf[3] << 8) | buf[4];
935 *h = (buf[1] << 8) | buf[2];
936 return( 0 );
940 /* ---------------------------------------------------------------------- */
941 /* Initialization */
944 int attach_slm( int target, int lun )
946 { static int did_register = 0;
947 int len;
949 if (N_SLM_Printers >= MAX_SLM) {
950 printk( KERN_WARNING "Too much SLMs\n" );
951 return( 0 );
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 );
964 /* read status and header of return data */
965 if (!acsi_extstatus( SLMBuffer, 6 ))
966 goto inq_timeout;
968 if (SLMBuffer[1] != 2) { /* device type == printer? */
969 printk( KERN_ERR "SLM inquiry returned device type != printer\n" );
970 goto inq_fail;
972 len = SLMBuffer[5];
974 /* read id string */
975 if (!acsi_extstatus( SLMBuffer, len ))
976 goto inq_timeout;
977 acsi_end_extstatus();
978 SLMBuffer[len] = 0;
980 if (!did_register) {
981 did_register = 1;
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;
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 );
997 int slm_init( void )
1000 if (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 unregister_chrdev( MAJOR_NR, "slm" );
1008 return -ENOMEM;
1010 BufferP = SLMBuffer;
1011 SLMState = IDLE;
1013 return 0;
1016 #ifdef MODULE
1018 /* from acsi.c */
1019 void acsi_attach_SLMs( int (*attach_func)( int, int ) );
1021 int init_module(void)
1023 int err;
1025 if ((err = slm_init()))
1026 return( err );
1027 /* This calls attach_slm() for every target/lun where acsi.c detected a
1028 * printer */
1029 acsi_attach_SLMs( attach_slm );
1030 return( 0 );
1033 void cleanup_module(void)
1035 if (unregister_chrdev( MAJOR_NR, "slm" ) != 0)
1036 printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
1037 atari_stram_free( SLMBuffer );
1039 #endif