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