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