1d9d9b4f48ccca9070e02fb6bcacbdc465ad9700
[sfrench/cifs-2.6.git] / 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
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>
78
79
80 #undef  DEBUG
81
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
85
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.
93  */
94 #define SLM_CONT_CNT_REPROG
95
96 #define CMDSET_TARG_LUN(cmd,targ,lun)                   \
97     do {                                                                                \
98                 cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5;  \
99                 cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5;   \
100         } while(0)
101
102 #define START_TIMER(to) mod_timer(&slm_timer, jiffies + (to))
103 #define STOP_TIMER()    del_timer(&slm_timer)
104
105
106 static char slmreqsense_cmd[6] = { 0x03, 0, 0, 0, 0, 0 };
107 static char slmprint_cmd[6]    = { 0x0a, 0, 0, 0, 0, 0 };
108 static char slminquiry_cmd[6]  = { 0x12, 0, 0, 0, 0, 0x80 };
109 static char slmmsense_cmd[6]   = { 0x1a, 0, 0, 0, 255, 0 };
110 #if 0
111 static char slmmselect_cmd[6]  = { 0x15, 0, 0, 0, 0, 0 };
112 #endif
113
114
115 #define MAX_SLM         2
116
117 static struct slm {
118         unsigned        target;                 /* target number */
119         unsigned        lun;                    /* LUN in target controller */
120         atomic_t        wr_ok;                  /* set to 0 if output part busy */
121         atomic_t        rd_ok;                  /* set to 0 if status part busy */
122 } slm_info[MAX_SLM];
123
124 int N_SLM_Printers = 0;
125
126 /* printer buffer */
127 static unsigned char    *SLMBuffer;     /* start of buffer */
128 static unsigned char    *BufferP;       /* current position in buffer */
129 static int                              BufferSize;     /* length of buffer for page size */
130
131 typedef enum { IDLE, FILLING, PRINTING } SLMSTATE;
132 static SLMSTATE                 SLMState;
133 static int                              SLMBufOwner;    /* SLM# currently using the buffer */
134
135 /* DMA variables */
136 #ifndef SLM_CONT_CNT_REPROG
137 static unsigned long    SLMCurAddr;             /* current base addr of DMA chunk */
138 static unsigned long    SLMEndAddr;             /* expected end addr */
139 static unsigned long    SLMSliceSize;   /* size of one DMA chunk */
140 #endif
141 static int                              SLMError;
142
143 /* wait queues */
144 static DECLARE_WAIT_QUEUE_HEAD(slm_wait);       /* waiting for buffer */
145 static DECLARE_WAIT_QUEUE_HEAD(print_wait);     /* waiting for printing finished */
146
147 /* status codes */
148 #define SLMSTAT_OK              0x00
149 #define SLMSTAT_ORNERY  0x02
150 #define SLMSTAT_TONER   0x03
151 #define SLMSTAT_WARMUP  0x04
152 #define SLMSTAT_PAPER   0x05
153 #define SLMSTAT_DRUM    0x06
154 #define SLMSTAT_INJAM   0x07
155 #define SLMSTAT_THRJAM  0x08
156 #define SLMSTAT_OUTJAM  0x09
157 #define SLMSTAT_COVER   0x0a
158 #define SLMSTAT_FUSER   0x0b
159 #define SLMSTAT_IMAGER  0x0c
160 #define SLMSTAT_MOTOR   0x0d
161 #define SLMSTAT_VIDEO   0x0e
162 #define SLMSTAT_SYSTO   0x10
163 #define SLMSTAT_OPCODE  0x12
164 #define SLMSTAT_DEVNUM  0x15
165 #define SLMSTAT_PARAM   0x1a
166 #define SLMSTAT_ACSITO  0x1b    /* driver defined */
167 #define SLMSTAT_NOTALL  0x1c    /* driver defined */
168
169 static char *SLMErrors[] = {
170         /* 0x00 */      "OK and ready",
171         /* 0x01 */      NULL,
172         /* 0x02 */      "ornery printer",
173         /* 0x03 */      "toner empty",
174         /* 0x04 */      "warming up",
175         /* 0x05 */      "paper empty",
176         /* 0x06 */      "drum empty",
177         /* 0x07 */      "input jam",
178         /* 0x08 */      "through jam",
179         /* 0x09 */      "output jam",
180         /* 0x0a */      "cover open",
181         /* 0x0b */      "fuser malfunction",
182         /* 0x0c */      "imager malfunction",
183         /* 0x0d */      "motor malfunction",
184         /* 0x0e */      "video malfunction",
185         /* 0x0f */      NULL,
186         /* 0x10 */      "printer system timeout",
187         /* 0x11 */      NULL,
188         /* 0x12 */      "invalid operation code",
189         /* 0x13 */      NULL,
190         /* 0x14 */      NULL,
191         /* 0x15 */      "invalid device number",
192         /* 0x16 */      NULL,
193         /* 0x17 */      NULL,
194         /* 0x18 */      NULL,
195         /* 0x19 */      NULL,
196         /* 0x1a */      "invalid parameter list",
197         /* 0x1b */      "ACSI timeout",
198         /* 0x1c */      "not all printed"
199 };
200
201 #define N_ERRORS        (sizeof(SLMErrors)/sizeof(*SLMErrors))
202
203 /* real (driver caused) error? */
204 #define IS_REAL_ERROR(x)        (x > 0x10)
205
206
207 static struct {
208         char    *name;
209         int     w, h;
210 } StdPageSize[] = {
211         { "Letter", 2400, 3180 },
212         { "Legal",  2400, 4080 },
213         { "A4",     2336, 3386 },
214         { "B5",     2016, 2914 }
215 };
216
217 #define N_STD_SIZES             (sizeof(StdPageSize)/sizeof(*StdPageSize))
218
219 #define SLM_BUFFER_SIZE (2336*3386/8)   /* A4 for now */
220 #define SLM_DMA_AMOUNT  255                             /* #sectors to program the DMA for */
221
222 #ifdef  SLM_CONTINUOUS_DMA
223 # define        SLM_DMA_INT_OFFSET      0               /* DMA goes until seccnt 0, no offs */
224 # define        SLM_DMA_END_OFFSET      32              /* 32 Byte ST-DMA FIFO */
225 # define        SLM_SLICE_SIZE(w)       (255*512)
226 #else
227 # define        SLM_DMA_INT_OFFSET      32              /* 32 Byte ST-DMA FIFO */
228 # define        SLM_DMA_END_OFFSET      32              /* 32 Byte ST-DMA FIFO */
229 # define        SLM_SLICE_SIZE(w)       ((254*512)/(w/8)*(w/8))
230 #endif
231
232 /* calculate the number of jiffies to wait for 'n' bytes */
233 #ifdef SLM_CONT_CNT_REPROG
234 #define DMA_TIME_FOR(n)         50
235 #define DMA_STARTUP_TIME        0
236 #else
237 #define DMA_TIME_FOR(n)         (n/1400-1)
238 #define DMA_STARTUP_TIME        650
239 #endif
240
241 /***************************** Prototypes *****************************/
242
243 static char *slm_errstr( int stat );
244 static int slm_getstats( char *buffer, int device );
245 static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t
246                          *ppos );
247 static void start_print( int device );
248 static irqreturn_t slm_interrupt(int irc, void *data);
249 static void slm_test_ready( unsigned long dummy );
250 static void set_dma_addr( unsigned long paddr );
251 static unsigned long get_dma_addr( void );
252 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
253                           loff_t *ppos );
254 static int slm_ioctl( struct inode *inode, struct file *file, unsigned int
255                       cmd, unsigned long arg );
256 static int slm_open( struct inode *inode, struct file *file );
257 static int slm_release( struct inode *inode, struct file *file );
258 static int slm_req_sense( int device );
259 static int slm_mode_sense( int device, char *buffer, int abs_flag );
260 #if 0
261 static int slm_mode_select( int device, char *buffer, int len, int
262                             default_flag );
263 #endif
264 static int slm_get_pagesize( int device, int *w, int *h );
265
266 /************************* End of Prototypes **************************/
267
268
269 static DEFINE_TIMER(slm_timer, slm_test_ready, 0, 0);
270
271 static const struct file_operations slm_fops = {
272         .owner =        THIS_MODULE,
273         .read =         slm_read,
274         .write =        slm_write,
275         .ioctl =        slm_ioctl,
276         .open =         slm_open,
277         .release =      slm_release,
278 };
279
280
281 /* ---------------------------------------------------------------------- */
282 /*                                                         Status Functions                                                       */
283
284
285 static char *slm_errstr( int stat )
286
287 {       char *p;
288         static char     str[22];
289
290         stat &= 0x1f;
291         if (stat >= 0 && stat < N_ERRORS && (p = SLMErrors[stat]))
292                 return( p );
293         sprintf( str, "unknown status 0x%02x", stat );
294         return( str );
295 }
296
297
298 static int slm_getstats( char *buffer, int device )
299
300 {       int                     len = 0, stat, i, w, h;
301         unsigned char   buf[256];
302         
303         stat = slm_mode_sense( device, buf, 0 );
304         if (IS_REAL_ERROR(stat))
305                 return( -EIO );
306         
307 #define SHORTDATA(i)            ((buf[i] << 8) | buf[i+1])
308 #define BOOLDATA(i,mask)        ((buf[i] & mask) ? "on" : "off")
309
310         w = SHORTDATA( 3 );
311         h = SHORTDATA( 1 );
312                 
313         len += sprintf( buffer+len, "Status\t\t%s\n",
314                                         slm_errstr( stat ) );
315         len += sprintf( buffer+len, "Page Size\t%dx%d",
316                                         w, h );
317
318         for( i = 0; i < N_STD_SIZES; ++i ) {
319                 if (w == StdPageSize[i].w && h == StdPageSize[i].h)
320                         break;
321         }
322         if (i < N_STD_SIZES)
323                 len += sprintf( buffer+len, " (%s)", StdPageSize[i].name );
324         buffer[len++] = '\n';
325
326         len += sprintf( buffer+len, "Top/Left Margin\t%d/%d\n",
327                                         SHORTDATA( 5 ), SHORTDATA( 7 ) );
328         len += sprintf( buffer+len, "Manual Feed\t%s\n",
329                                         BOOLDATA( 9, 0x01 ) );
330         len += sprintf( buffer+len, "Input Select\t%d\n",
331                                         (buf[9] >> 1) & 7 );
332         len += sprintf( buffer+len, "Auto Select\t%s\n",
333                                         BOOLDATA( 9, 0x10 ) );
334         len += sprintf( buffer+len, "Prefeed Paper\t%s\n",
335                                         BOOLDATA( 9, 0x20 ) );
336         len += sprintf( buffer+len, "Thick Pixels\t%s\n",
337                                         BOOLDATA( 9, 0x40 ) );
338         len += sprintf( buffer+len, "H/V Resol.\t%d/%d dpi\n",
339                                         SHORTDATA( 12 ), SHORTDATA( 10 ) );
340         len += sprintf( buffer+len, "System Timeout\t%d\n",
341                                         buf[14] );
342         len += sprintf( buffer+len, "Scan Time\t%d\n",
343                                         SHORTDATA( 15 ) );
344         len += sprintf( buffer+len, "Page Count\t%d\n",
345                                         SHORTDATA( 17 ) );
346         len += sprintf( buffer+len, "In/Out Cap.\t%d/%d\n",
347                                         SHORTDATA( 19 ), SHORTDATA( 21 ) );
348         len += sprintf( buffer+len, "Stagger Output\t%s\n",
349                                         BOOLDATA( 23, 0x01 ) );
350         len += sprintf( buffer+len, "Output Select\t%d\n",
351                                         (buf[23] >> 1) & 7 );
352         len += sprintf( buffer+len, "Duplex Print\t%s\n",
353                                         BOOLDATA( 23, 0x10 ) );
354         len += sprintf( buffer+len, "Color Sep.\t%s\n",
355                                         BOOLDATA( 23, 0x20 ) );
356
357         return( len );
358 }
359
360
361 static ssize_t slm_read( struct file *file, char *buf, size_t count,
362                                                  loff_t *ppos )
363
364 {
365         struct inode *node = file->f_path.dentry->d_inode;
366         unsigned long page;
367         int length;
368         int end;
369
370         if (!(page = __get_free_page( GFP_KERNEL )))
371                 return( -ENOMEM );
372         
373         length = slm_getstats( (char *)page, iminor(node) );
374         if (length < 0) {
375                 count = length;
376                 goto out;
377         }
378         if (file->f_pos >= length) {
379                 count = 0;
380                 goto out;
381         }
382         if (count + file->f_pos > length)
383                 count = length - file->f_pos;
384         end = count + file->f_pos;
385         if (copy_to_user(buf, (char *)page + file->f_pos, count)) {
386                 count = -EFAULT;
387                 goto out;
388         }
389         file->f_pos = end;
390 out:    free_page( page );
391         return( count );
392 }
393
394
395 /* ---------------------------------------------------------------------- */
396 /*                                                                 Printing                                                               */
397
398
399 static void start_print( int device )
400
401 {       struct slm *sip = &slm_info[device];
402         unsigned char   *cmd;
403         unsigned long   paddr;
404         int                             i;
405         
406         stdma_lock( slm_interrupt, NULL );
407
408         CMDSET_TARG_LUN( slmprint_cmd, sip->target, sip->lun );
409         cmd = slmprint_cmd;
410         paddr = virt_to_phys( SLMBuffer );
411         dma_cache_maintenance( paddr, virt_to_phys(BufferP)-paddr, 1 );
412         DISABLE_IRQ();
413
414         /* Low on A1 */
415         dma_wd.dma_mode_status = 0x88;
416         MFPDELAY();
417
418         /* send the command bytes except the last */
419         for( i = 0; i < 5; ++i ) {
420                 DMA_LONG_WRITE( *cmd++, 0x8a );
421                 udelay(20);
422                 if (!acsi_wait_for_IRQ( HZ/2 )) {
423                         SLMError = 1;
424                         return; /* timeout */
425                 }
426         }
427         /* last command byte */
428         DMA_LONG_WRITE( *cmd++, 0x82 );
429         MFPDELAY();
430         /* set DMA address */
431         set_dma_addr( paddr );
432         /* program DMA for write and select sector counter reg */
433         dma_wd.dma_mode_status = 0x192;
434         MFPDELAY();
435         /* program for 255*512 bytes and start DMA */
436         DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
437
438 #ifndef SLM_CONT_CNT_REPROG
439         SLMCurAddr = paddr;
440         SLMEndAddr = paddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
441 #endif
442         START_TIMER( DMA_STARTUP_TIME + DMA_TIME_FOR( SLMSliceSize ));
443 #if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG)
444         printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
445                         SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
446 #endif
447         
448         ENABLE_IRQ();
449 }
450
451
452 /* Only called when an error happened or at the end of a page */
453
454 static irqreturn_t slm_interrupt(int irc, void *data)
455
456 {       unsigned long   addr;
457         int                             stat;
458         
459         STOP_TIMER();
460         addr = get_dma_addr();
461         stat = acsi_getstatus();
462         SLMError = (stat < 0)             ? SLMSTAT_ACSITO :
463                        (addr < virt_to_phys(BufferP)) ? SLMSTAT_NOTALL :
464                                                                             stat;
465
466         dma_wd.dma_mode_status = 0x80;
467         MFPDELAY();
468 #ifdef DEBUG
469         printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr, SLMError );
470 #endif
471
472         wake_up( &print_wait );
473         stdma_release();
474         ENABLE_IRQ();
475         return IRQ_HANDLED;
476 }
477
478
479 static void slm_test_ready( unsigned long dummy )
480
481 {
482 #ifdef SLM_CONT_CNT_REPROG
483         /* program for 255*512 bytes again */
484         dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
485         START_TIMER( DMA_TIME_FOR(0) );
486 #ifdef DEBUG
487         printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
488                         DMA_TIME_FOR(0), get_dma_addr() );
489 #endif
490         
491 #else /* !SLM_CONT_CNT_REPROG */
492
493         unsigned long   flags, addr;
494         int                             d, ti;
495 #ifdef DEBUG
496         struct timeval start_tm, end_tm;
497         int                        did_wait = 0;
498 #endif
499
500         local_irq_save(flags);
501
502         addr = get_dma_addr();
503         if ((d = SLMEndAddr - addr) > 0) {
504                 local_irq_restore(flags);
505                 
506                 /* slice not yet finished, decide whether to start another timer or to
507                  * busy-wait */
508                 ti = DMA_TIME_FOR( d );
509                 if (ti > 0) {
510 #ifdef DEBUG
511                         printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
512                                         ti, d );
513 #endif
514                         START_TIMER( ti );
515                         return;
516                 }
517                 /* wait for desired end address to be reached */
518 #ifdef DEBUG
519                 do_gettimeofday( &start_tm );
520                 did_wait = 1;
521 #endif
522                 local_irq_disable();
523                 while( get_dma_addr() < SLMEndAddr )
524                         barrier();
525         }
526
527         /* slice finished, start next one */
528         SLMCurAddr += SLMSliceSize;
529
530 #ifdef SLM_CONTINUOUS_DMA
531         /* program for 255*512 bytes again */
532         dma_wd.fdc_acces_seccount = SLM_DMA_AMOUNT;
533 #else
534         /* set DMA address;
535          * add 2 bytes for the ones in the SLM controller FIFO! */
536         set_dma_addr( SLMCurAddr + 2 );
537         /* toggle DMA to write and select sector counter reg */
538         dma_wd.dma_mode_status = 0x92;
539         MFPDELAY();
540         dma_wd.dma_mode_status = 0x192;
541         MFPDELAY();
542         /* program for 255*512 bytes and start DMA */
543         DMA_LONG_WRITE( SLM_DMA_AMOUNT, 0x112 );
544 #endif
545         
546         local_irq_restore(flags);
547
548 #ifdef DEBUG
549         if (did_wait) {
550                 int ms;
551                 do_gettimeofday( &end_tm );
552                 ms = (end_tm.tv_sec*1000000+end_tm.tv_usec) -
553                          (start_tm.tv_sec*1000000+start_tm.tv_usec); 
554                 printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n",
555                                 ms/1000, ms%1000, d );
556         }
557         else
558                 printk( "SLM: didn't wait (!)\n" );
559 #endif
560
561         if ((unsigned char *)PTOV( SLMCurAddr + SLMSliceSize ) >= BufferP) {
562                 /* will be last slice, no timer necessary */
563 #ifdef DEBUG
564                 printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
565                                 SLMCurAddr, SLMEndAddr );
566 #endif
567         }
568         else {
569                 /* not last slice */
570                 SLMEndAddr = SLMCurAddr + SLMSliceSize + SLM_DMA_INT_OFFSET;
571                 START_TIMER( DMA_TIME_FOR( SLMSliceSize ));
572 #ifdef DEBUG
573                 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
574                                 SLMCurAddr, SLMEndAddr, DMA_TIME_FOR( SLMSliceSize ) );
575 #endif
576         }
577 #endif /* SLM_CONT_CNT_REPROG */
578 }
579
580
581 static void set_dma_addr( unsigned long paddr )
582
583 {       unsigned long flags;
584
585         local_irq_save(flags);
586         dma_wd.dma_lo = (unsigned char)paddr;
587         paddr >>= 8;
588         MFPDELAY();
589         dma_wd.dma_md = (unsigned char)paddr;
590         paddr >>= 8;
591         MFPDELAY();
592         if (ATARIHW_PRESENT( EXTD_DMA ))
593                 st_dma_ext_dmahi = (unsigned short)paddr;
594         else
595                 dma_wd.dma_hi = (unsigned char)paddr;
596         MFPDELAY();
597         local_irq_restore(flags);
598 }
599
600
601 static unsigned long get_dma_addr( void )
602
603 {       unsigned long   addr;
604         
605         addr = dma_wd.dma_lo & 0xff;
606         MFPDELAY();
607         addr |= (dma_wd.dma_md & 0xff) << 8;
608         MFPDELAY();
609         addr |= (dma_wd.dma_hi & 0xff) << 16;
610         MFPDELAY();
611
612         return( addr );
613 }
614
615
616 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
617                                                   loff_t *ppos )
618
619 {
620         struct inode *node = file->f_path.dentry->d_inode;
621         int             device = iminor(node);
622         int             n, filled, w, h;
623
624         while( SLMState == PRINTING ||
625                    (SLMState == FILLING && SLMBufOwner != device) ) {
626                 interruptible_sleep_on( &slm_wait );
627                 if (signal_pending(current))
628                         return( -ERESTARTSYS );
629         }
630         if (SLMState == IDLE) {
631                 /* first data of page: get current page size  */
632                 if (slm_get_pagesize( device, &w, &h ))
633                         return( -EIO );
634                 BufferSize = w*h/8;
635                 if (BufferSize > SLM_BUFFER_SIZE)
636                         return( -ENOMEM );
637
638                 SLMState = FILLING;
639                 SLMBufOwner = device;
640         }
641
642         n = count;
643         filled = BufferP - SLMBuffer;
644         if (filled + n > BufferSize)
645                 n = BufferSize - filled;
646
647         if (copy_from_user(BufferP, buf, n))
648                 return -EFAULT;
649         BufferP += n;
650         filled += n;
651
652         if (filled == BufferSize) {
653                 /* Check the paper size again! The user may have switched it in the
654                  * time between starting the data and finishing them. Would end up in
655                  * a trashy page... */
656                 if (slm_get_pagesize( device, &w, &h ))
657                         return( -EIO );
658                 if (BufferSize != w*h/8) {
659                         printk( KERN_NOTICE "slm%d: page size changed while printing\n",
660                                         device );
661                         return( -EAGAIN );
662                 }
663
664                 SLMState = PRINTING;
665                 /* choose a slice size that is a multiple of the line size */
666 #ifndef SLM_CONT_CNT_REPROG
667                 SLMSliceSize = SLM_SLICE_SIZE(w);
668 #endif
669                 
670                 start_print( device );
671                 sleep_on( &print_wait );
672                 if (SLMError && IS_REAL_ERROR(SLMError)) {
673                         printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) );
674                         n = -EIO;
675                 }
676
677                 SLMState = IDLE;
678                 BufferP = SLMBuffer;
679                 wake_up_interruptible( &slm_wait );
680         }
681         
682         return( n );
683 }
684
685
686 /* ---------------------------------------------------------------------- */
687 /*                                                         ioctl Functions                                                        */
688
689
690 static int slm_ioctl( struct inode *inode, struct file *file,
691                                           unsigned int cmd, unsigned long arg )
692
693 {       int             device = iminor(inode), err;
694         
695         /* I can think of setting:
696          *  - manual feed
697          *  - paper format
698          *  - copy count
699          *  - ...
700          * but haven't implemented that yet :-)
701          * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
702          */
703         switch( cmd ) {
704
705           case SLMIORESET:              /* reset buffer, i.e. empty the buffer */
706                 if (!(file->f_mode & 2))
707                         return( -EINVAL );
708                 if (SLMState == PRINTING)
709                         return( -EBUSY );
710                 SLMState = IDLE;
711                 BufferP = SLMBuffer;
712                 wake_up_interruptible( &slm_wait );
713                 return( 0 );
714                 
715           case SLMIOGSTAT: {    /* get status */
716                 int stat;
717                 char *str;
718
719                 stat = slm_req_sense( device );
720                 if (arg) {
721                         str = slm_errstr( stat );
722                         if (put_user(stat,
723                                      (long *)&((struct SLM_status *)arg)->stat))
724                                 return -EFAULT;
725                         if (copy_to_user( ((struct SLM_status *)arg)->str, str,
726                                                  strlen(str) + 1))
727                                 return -EFAULT;
728                 }
729                 return( stat );
730           }
731                 
732           case SLMIOGPSIZE: {   /* get paper size */
733                 int w, h;
734                 
735                 if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
736                 
737                 if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
738                         return -EFAULT;
739                 if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height))
740                         return -EFAULT;
741                 return( 0 );
742           }
743                 
744           case SLMIOGMFEED:     /* get manual feed */
745                 return( -EINVAL );
746
747           case SLMIOSPSIZE:     /* set paper size */
748                 return( -EINVAL );
749
750           case SLMIOSMFEED:     /* set manual feed */
751                 return( -EINVAL );
752
753         }
754         return( -EINVAL );
755 }
756
757
758 /* ---------------------------------------------------------------------- */
759 /*                                                       Opening and Closing                                              */
760
761
762 static int slm_open( struct inode *inode, struct file *file )
763
764 {       int device;
765         struct slm *sip;
766         
767         device = iminor(inode);
768         if (device >= N_SLM_Printers)
769                 return( -ENXIO );
770         sip = &slm_info[device];
771
772         if (file->f_mode & 2) {
773                 /* open for writing is exclusive */
774                 if ( !atomic_dec_and_test(&sip->wr_ok) ) {
775                         atomic_inc(&sip->wr_ok);        
776                         return( -EBUSY );
777                 }
778         }
779         if (file->f_mode & 1) {
780                 /* open for reading is exclusive */
781                 if ( !atomic_dec_and_test(&sip->rd_ok) ) {
782                         atomic_inc(&sip->rd_ok);
783                         return( -EBUSY );
784                 }
785         }
786
787         return( 0 );
788 }
789
790
791 static int slm_release( struct inode *inode, struct file *file )
792
793 {       int device;
794         struct slm *sip;
795         
796         device = iminor(inode);
797         sip = &slm_info[device];
798
799         if (file->f_mode & 2)
800                 atomic_inc( &sip->wr_ok );
801         if (file->f_mode & 1)
802                 atomic_inc( &sip->rd_ok );
803         
804         return( 0 );
805 }
806
807
808 /* ---------------------------------------------------------------------- */
809 /*                                               ACSI Primitives for the SLM                                      */
810
811
812 static int slm_req_sense( int device )
813
814 {       int                     stat, rv;
815         struct slm *sip = &slm_info[device];
816         
817         stdma_lock( NULL, NULL );
818
819         CMDSET_TARG_LUN( slmreqsense_cmd, sip->target, sip->lun );
820         if (!acsicmd_nodma( slmreqsense_cmd, 0 ) ||
821                 (stat = acsi_getstatus()) < 0)
822                 rv = SLMSTAT_ACSITO;
823         else
824                 rv = stat & 0x1f;
825
826         ENABLE_IRQ();
827         stdma_release();
828         return( rv );
829 }
830
831
832 static int slm_mode_sense( int device, char *buffer, int abs_flag )
833
834 {       unsigned char   stat, len;
835         int                             rv = 0;
836         struct slm              *sip = &slm_info[device];
837         
838         stdma_lock( NULL, NULL );
839
840         CMDSET_TARG_LUN( slmmsense_cmd, sip->target, sip->lun );
841         slmmsense_cmd[5] = abs_flag ? 0x80 : 0;
842         if (!acsicmd_nodma( slmmsense_cmd, 0 )) {
843                 rv = SLMSTAT_ACSITO;
844                 goto the_end;
845         }
846
847         if (!acsi_extstatus( &stat, 1 )) {
848                 acsi_end_extstatus();
849                 rv = SLMSTAT_ACSITO;
850                 goto the_end;
851         }
852         
853         if (!acsi_extstatus( &len, 1 )) {
854                 acsi_end_extstatus();
855                 rv = SLMSTAT_ACSITO;
856                 goto the_end;
857         }
858         buffer[0] = len;
859         if (!acsi_extstatus( buffer+1, len )) {
860                 acsi_end_extstatus();
861                 rv = SLMSTAT_ACSITO;
862                 goto the_end;
863         }
864         
865         acsi_end_extstatus();
866         rv = stat & 0x1f;
867
868   the_end:
869         ENABLE_IRQ();
870         stdma_release();
871         return( rv );
872 }
873
874
875 #if 0
876 /* currently unused */
877 static int slm_mode_select( int device, char *buffer, int len,
878                                                         int default_flag )
879
880 {       int                     stat, rv;
881         struct slm      *sip = &slm_info[device];
882         
883         stdma_lock( NULL, NULL );
884
885         CMDSET_TARG_LUN( slmmselect_cmd, sip->target, sip->lun );
886         slmmselect_cmd[5] = default_flag ? 0x80 : 0;
887         if (!acsicmd_nodma( slmmselect_cmd, 0 )) {
888                 rv = SLMSTAT_ACSITO;
889                 goto the_end;
890         }
891
892         if (!default_flag) {
893                 unsigned char c = len;
894                 if (!acsi_extcmd( &c, 1 )) {
895                         rv = SLMSTAT_ACSITO;
896                         goto the_end;
897                 }
898                 if (!acsi_extcmd( buffer, len )) {
899                         rv = SLMSTAT_ACSITO;
900                         goto the_end;
901                 }
902         }
903         
904         stat = acsi_getstatus();
905         rv = (stat < 0 ? SLMSTAT_ACSITO : stat);
906
907   the_end:
908         ENABLE_IRQ();
909         stdma_release();
910         return( rv );
911 }
912 #endif
913
914
915 static int slm_get_pagesize( int device, int *w, int *h )
916
917 {       char    buf[256];
918         int             stat;
919         
920         stat = slm_mode_sense( device, buf, 0 );
921         ENABLE_IRQ();
922         stdma_release();
923
924         if (stat != SLMSTAT_OK)
925                 return( -EIO );
926
927         *w = (buf[3] << 8) | buf[4];
928         *h = (buf[1] << 8) | buf[2];
929         return( 0 );
930 }
931
932
933 /* ---------------------------------------------------------------------- */
934 /*                                                              Initialization                                                    */
935
936
937 int attach_slm( int target, int lun )
938
939 {       static int      did_register;
940         int                     len;
941
942         if (N_SLM_Printers >= MAX_SLM) {
943                 printk( KERN_WARNING "Too much SLMs\n" );
944                 return( 0 );
945         }
946         
947         /* do an INQUIRY */
948         udelay(100);
949         CMDSET_TARG_LUN( slminquiry_cmd, target, lun );
950         if (!acsicmd_nodma( slminquiry_cmd, 0 )) {
951           inq_timeout:
952                 printk( KERN_ERR "SLM inquiry command timed out.\n" );
953           inq_fail:
954                 acsi_end_extstatus();
955                 return( 0 );
956         }
957         /* read status and header of return data */
958         if (!acsi_extstatus( SLMBuffer, 6 ))
959                 goto inq_timeout;
960
961         if (SLMBuffer[1] != 2) { /* device type == printer? */
962                 printk( KERN_ERR "SLM inquiry returned device type != printer\n" );
963                 goto inq_fail;
964         }
965         len = SLMBuffer[5];
966         
967         /* read id string */
968         if (!acsi_extstatus( SLMBuffer, len ))
969                 goto inq_timeout;
970         acsi_end_extstatus();
971         SLMBuffer[len] = 0;
972
973         if (!did_register) {
974                 did_register = 1;
975         }
976
977         slm_info[N_SLM_Printers].target = target;
978         slm_info[N_SLM_Printers].lun    = lun;
979         atomic_set(&slm_info[N_SLM_Printers].wr_ok, 1 ); 
980         atomic_set(&slm_info[N_SLM_Printers].rd_ok, 1 );
981         
982         printk( KERN_INFO "  Printer: %s\n", SLMBuffer );
983         printk( KERN_INFO "Detected slm%d at id %d lun %d\n",
984                         N_SLM_Printers, target, lun );
985         N_SLM_Printers++;
986         return( 1 );
987 }
988
989 int slm_init( void )
990
991 {
992         int i;
993         if (register_chrdev( ACSI_MAJOR, "slm", &slm_fops )) {
994                 printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", ACSI_MAJOR );
995                 return -EBUSY;
996         }
997         
998         if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, "SLM" ))) {
999                 printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" );
1000                 unregister_chrdev( ACSI_MAJOR, "slm" );
1001                 return -ENOMEM;
1002         }
1003         BufferP = SLMBuffer;
1004         SLMState = IDLE;
1005         
1006         return 0;
1007 }
1008
1009 #ifdef MODULE
1010
1011 /* from acsi.c */
1012 void acsi_attach_SLMs( int (*attach_func)( int, int ) );
1013
1014 int init_module(void)
1015 {
1016         int err;
1017
1018         if ((err = slm_init()))
1019                 return( err );
1020         /* This calls attach_slm() for every target/lun where acsi.c detected a
1021          * printer */
1022         acsi_attach_SLMs( attach_slm );
1023         return( 0 );
1024 }
1025
1026 void cleanup_module(void)
1027 {
1028         if (unregister_chrdev( ACSI_MAJOR, "slm" ) != 0)
1029                 printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
1030         atari_stram_free( SLMBuffer );
1031 }
1032 #endif