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