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