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