2 * acsi_slm.c -- Device driver for the Atari SLM laser printer
4 * Copyright 1995 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
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
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.
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:
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.
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
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)...
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
55 #include <linux/module.h>
57 #include <linux/errno.h>
58 #include <linux/sched.h>
59 #include <linux/timer.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>
67 #include <linux/slab.h>
68 #include <linux/devfs_fs_kernel.h>
69 #include <linux/smp_lock.h>
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>
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
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.
96 #define SLM_CONT_CNT_REPROG
98 #define CMDSET_TARG_LUN(cmd,targ,lun) \
100 cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \
101 cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \
104 #define START_TIMER(to) mod_timer(&slm_timer, jiffies + (to))
105 #define STOP_TIMER() del_timer(&slm_timer)
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 };
113 static char slmmselect_cmd
[6] = { 0x15, 0, 0, 0, 0, 0 };
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 */
126 int N_SLM_Printers
= 0;
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 */
133 typedef enum { IDLE
, FILLING
, PRINTING
} SLMSTATE
;
134 static SLMSTATE SLMState
;
135 static int SLMBufOwner
; /* SLM# currently using the buffer */
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 */
146 static DECLARE_WAIT_QUEUE_HEAD(slm_wait
); /* waiting for buffer */
147 static DECLARE_WAIT_QUEUE_HEAD(print_wait
); /* waiting for printing finished */
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 */
171 static char *SLMErrors
[] = {
172 /* 0x00 */ "OK and ready",
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",
188 /* 0x10 */ "printer system timeout",
190 /* 0x12 */ "invalid operation code",
193 /* 0x15 */ "invalid device number",
198 /* 0x1a */ "invalid parameter list",
199 /* 0x1b */ "ACSI timeout",
200 /* 0x1c */ "not all printed"
203 #define N_ERRORS (sizeof(SLMErrors)/sizeof(*SLMErrors))
205 /* real (driver caused) error? */
206 #define IS_REAL_ERROR(x) (x > 0x10)
213 { "Letter", 2400, 3180 },
214 { "Legal", 2400, 4080 },
215 { "A4", 2336, 3386 },
219 #define N_STD_SIZES (sizeof(StdPageSize)/sizeof(*StdPageSize))
221 #define SLM_BUFFER_SIZE (2336*3386/8) /* A4 for now */
222 #define SLM_DMA_AMOUNT 255 /* #sectors to program the DMA for */
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)
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))
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
239 #define DMA_TIME_FOR(n) (n/1400-1)
240 #define DMA_STARTUP_TIME 650
243 /***************************** Prototypes *****************************/
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
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
,
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
);
263 static int slm_mode_select( int device
, char *buffer
, int len
, int
266 static int slm_get_pagesize( int device
, int *w
, int *h
);
268 /************************* End of Prototypes **************************/
271 static struct timer_list slm_timer
= TIMER_INITIALIZER(slm_test_ready
, 0, 0);
273 static struct file_operations slm_fops
= {
274 .owner
= THIS_MODULE
,
279 .release
= slm_release
,
283 /* ---------------------------------------------------------------------- */
284 /* Status Functions */
287 static char *slm_errstr( int stat
)
293 if (stat
>= 0 && stat
< N_ERRORS
&& (p
= SLMErrors
[stat
]))
295 sprintf( str
, "unknown status 0x%02x", stat
);
300 static int slm_getstats( char *buffer
, int device
)
302 { int len
= 0, stat
, i
, w
, h
;
303 unsigned char buf
[256];
305 stat
= slm_mode_sense( device
, buf
, 0 );
306 if (IS_REAL_ERROR(stat
))
309 #define SHORTDATA(i) ((buf[i] << 8) | buf[i+1])
310 #define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off")
315 len
+= sprintf( buffer
+len
, "Status\t\t%s\n",
316 slm_errstr( stat
) );
317 len
+= sprintf( buffer
+len
, "Page Size\t%dx%d",
320 for( i
= 0; i
< N_STD_SIZES
; ++i
) {
321 if (w
== StdPageSize
[i
].w
&& h
== StdPageSize
[i
].h
)
325 len
+= sprintf( buffer
+len
, " (%s)", StdPageSize
[i
].name
);
326 buffer
[len
++] = '\n';
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",
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",
344 len
+= sprintf( buffer
+len
, "Scan Time\t%d\n",
346 len
+= sprintf( buffer
+len
, "Page Count\t%d\n",
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 ) );
363 static ssize_t
slm_read( struct file
*file
, char *buf
, size_t count
,
367 struct inode
*node
= file
->f_dentry
->d_inode
;
374 if (!(page
= __get_free_page( GFP_KERNEL
)))
377 length
= slm_getstats( (char *)page
, iminor(node
) );
382 if (file
->f_pos
>= length
) {
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
)) {
394 out
: free_page( page
);
399 /* ---------------------------------------------------------------------- */
403 static void start_print( int device
)
405 { struct slm
*sip
= &slm_info
[device
];
410 stdma_lock( slm_interrupt
, NULL
);
412 CMDSET_TARG_LUN( slmprint_cmd
, sip
->target
, sip
->lun
);
414 paddr
= virt_to_phys( SLMBuffer
);
415 dma_cache_maintenance( paddr
, virt_to_phys(BufferP
)-paddr
, 1 );
419 dma_wd
.dma_mode_status
= 0x88;
422 /* send the command bytes except the last */
423 for( i
= 0; i
< 5; ++i
) {
424 DMA_LONG_WRITE( *cmd
++, 0x8a );
426 if (!acsi_wait_for_IRQ( HZ
/2 )) {
428 return; /* timeout */
431 /* last command byte */
432 DMA_LONG_WRITE( *cmd
++, 0x82 );
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;
439 /* program for 255*512 bytes and start DMA */
440 DMA_LONG_WRITE( SLM_DMA_AMOUNT
, 0x112 );
442 #ifndef SLM_CONT_CNT_REPROG
444 SLMEndAddr
= paddr
+ SLMSliceSize
+ SLM_DMA_INT_OFFSET
;
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
) );
456 /* Only called when an error happened or at the end of a page */
458 static irqreturn_t
slm_interrupt(int irc
, void *data
, struct pt_regs
*fp
)
460 { unsigned long addr
;
464 addr
= get_dma_addr();
465 stat
= acsi_getstatus();
466 SLMError
= (stat
< 0) ? SLMSTAT_ACSITO
:
467 (addr
< virt_to_phys(BufferP
)) ? SLMSTAT_NOTALL
:
470 dma_wd
.dma_mode_status
= 0x80;
473 printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr
, SLMError
);
476 wake_up( &print_wait
);
483 static void slm_test_ready( unsigned long dummy
)
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) );
491 printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
492 DMA_TIME_FOR(0), get_dma_addr() );
495 #else /* !SLM_CONT_CNT_REPROG */
497 unsigned long flags
, addr
;
500 struct timeval start_tm
, end_tm
;
504 local_irq_save(flags
);
506 addr
= get_dma_addr();
507 if ((d
= SLMEndAddr
- addr
) > 0) {
508 local_irq_restore(flags
);
510 /* slice not yet finished, decide whether to start another timer or to
512 ti
= DMA_TIME_FOR( d
);
515 printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
521 /* wait for desired end address to be reached */
523 do_gettimeofday( &start_tm
);
527 while( get_dma_addr() < SLMEndAddr
)
531 /* slice finished, start next one */
532 SLMCurAddr
+= SLMSliceSize
;
534 #ifdef SLM_CONTINUOUS_DMA
535 /* program for 255*512 bytes again */
536 dma_wd
.fdc_acces_seccount
= SLM_DMA_AMOUNT
;
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;
544 dma_wd
.dma_mode_status
= 0x192;
546 /* program for 255*512 bytes and start DMA */
547 DMA_LONG_WRITE( SLM_DMA_AMOUNT
, 0x112 );
550 local_irq_restore(flags
);
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
);
562 printk( "SLM: didn't wait (!)\n" );
565 if ((unsigned char *)PTOV( SLMCurAddr
+ SLMSliceSize
) >= BufferP
) {
566 /* will be last slice, no timer necessary */
568 printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
569 SLMCurAddr
, SLMEndAddr
);
574 SLMEndAddr
= SLMCurAddr
+ SLMSliceSize
+ SLM_DMA_INT_OFFSET
;
575 START_TIMER( DMA_TIME_FOR( SLMSliceSize
));
577 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
578 SLMCurAddr
, SLMEndAddr
, DMA_TIME_FOR( SLMSliceSize
) );
581 #endif /* SLM_CONT_CNT_REPROG */
585 static void set_dma_addr( unsigned long paddr
)
587 { unsigned long flags
;
589 local_irq_save(flags
);
590 dma_wd
.dma_lo
= (unsigned char)paddr
;
593 dma_wd
.dma_md
= (unsigned char)paddr
;
596 if (ATARIHW_PRESENT( EXTD_DMA
))
597 st_dma_ext_dmahi
= (unsigned short)paddr
;
599 dma_wd
.dma_hi
= (unsigned char)paddr
;
601 local_irq_restore(flags
);
605 static unsigned long get_dma_addr( void )
607 { unsigned long addr
;
609 addr
= dma_wd
.dma_lo
& 0xff;
611 addr
|= (dma_wd
.dma_md
& 0xff) << 8;
613 addr
|= (dma_wd
.dma_hi
& 0xff) << 16;
620 static ssize_t
slm_write( struct file
*file
, const char *buf
, size_t count
,
624 struct inode
*node
= file
->f_dentry
->d_inode
;
625 int device
= iminor(node
);
628 while( SLMState
== PRINTING
||
629 (SLMState
== FILLING
&& SLMBufOwner
!= device
) ) {
630 interruptible_sleep_on( &slm_wait
);
631 if (signal_pending(current
))
632 return( -ERESTARTSYS
);
634 if (SLMState
== IDLE
) {
635 /* first data of page: get current page size */
636 if (slm_get_pagesize( device
, &w
, &h
))
639 if (BufferSize
> SLM_BUFFER_SIZE
)
643 SLMBufOwner
= device
;
647 filled
= BufferP
- SLMBuffer
;
648 if (filled
+ n
> BufferSize
)
649 n
= BufferSize
- filled
;
651 if (copy_from_user(BufferP
, buf
, n
))
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
))
662 if (BufferSize
!= w
*h
/8) {
663 printk( KERN_NOTICE
"slm%d: page size changed while printing\n",
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
);
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
) );
683 wake_up_interruptible( &slm_wait
);
690 /* ---------------------------------------------------------------------- */
691 /* ioctl Functions */
694 static int slm_ioctl( struct inode
*inode
, struct file
*file
,
695 unsigned int cmd
, unsigned long arg
)
697 { int device
= iminor(inode
), err
;
699 /* I can think of setting:
704 * but haven't implemented that yet :-)
705 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
709 case SLMIORESET
: /* reset buffer, i.e. empty the buffer */
710 if (!(file
->f_mode
& 2))
712 if (SLMState
== PRINTING
)
716 wake_up_interruptible( &slm_wait
);
719 case SLMIOGSTAT
: { /* get status */
723 stat
= slm_req_sense( device
);
725 str
= slm_errstr( stat
);
727 (long *)&((struct SLM_status
*)arg
)->stat
))
729 if (copy_to_user( ((struct SLM_status
*)arg
)->str
, str
,
736 case SLMIOGPSIZE
: { /* get paper size */
739 if ((err
= slm_get_pagesize( device
, &w
, &h
))) return( err
);
741 if (put_user(w
, (long *)&((struct SLM_paper_size
*)arg
)->width
))
743 if (put_user(h
, (long *)&((struct SLM_paper_size
*)arg
)->height
))
748 case SLMIOGMFEED
: /* get manual feed */
751 case SLMIOSPSIZE
: /* set paper size */
754 case SLMIOSMFEED
: /* set manual feed */
762 /* ---------------------------------------------------------------------- */
763 /* Opening and Closing */
766 static int slm_open( struct inode
*inode
, struct file
*file
)
771 device
= iminor(inode
);
772 if (device
>= N_SLM_Printers
)
774 sip
= &slm_info
[device
];
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
);
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
);
795 static int slm_release( struct inode
*inode
, struct file
*file
)
800 device
= iminor(inode
);
801 sip
= &slm_info
[device
];
803 if (file
->f_mode
& 2)
804 atomic_inc( &sip
->wr_ok
);
805 if (file
->f_mode
& 1)
806 atomic_inc( &sip
->rd_ok
);
812 /* ---------------------------------------------------------------------- */
813 /* ACSI Primitives for the SLM */
816 static int slm_req_sense( int device
)
819 struct slm
*sip
= &slm_info
[device
];
821 stdma_lock( NULL
, NULL
);
823 CMDSET_TARG_LUN( slmreqsense_cmd
, sip
->target
, sip
->lun
);
824 if (!acsicmd_nodma( slmreqsense_cmd
, 0 ) ||
825 (stat
= acsi_getstatus()) < 0)
836 static int slm_mode_sense( int device
, char *buffer
, int abs_flag
)
838 { unsigned char stat
, len
;
840 struct slm
*sip
= &slm_info
[device
];
842 stdma_lock( NULL
, NULL
);
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 )) {
851 if (!acsi_extstatus( &stat
, 1 )) {
852 acsi_end_extstatus();
857 if (!acsi_extstatus( &len
, 1 )) {
858 acsi_end_extstatus();
863 if (!acsi_extstatus( buffer
+1, len
)) {
864 acsi_end_extstatus();
869 acsi_end_extstatus();
880 /* currently unused */
881 static int slm_mode_select( int device
, char *buffer
, int len
,
885 struct slm
*sip
= &slm_info
[device
];
887 stdma_lock( NULL
, NULL
);
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 )) {
897 unsigned char c
= len
;
898 if (!acsi_extcmd( &c
, 1 )) {
902 if (!acsi_extcmd( buffer
, len
)) {
908 stat
= acsi_getstatus();
909 rv
= (stat
< 0 ? SLMSTAT_ACSITO
: stat
);
919 static int slm_get_pagesize( int device
, int *w
, int *h
)
924 stat
= slm_mode_sense( device
, buf
, 0 );
928 if (stat
!= SLMSTAT_OK
)
931 *w
= (buf
[3] << 8) | buf
[4];
932 *h
= (buf
[1] << 8) | buf
[2];
937 /* ---------------------------------------------------------------------- */
941 int attach_slm( int target
, int lun
)
943 { static int did_register
;
946 if (N_SLM_Printers
>= MAX_SLM
) {
947 printk( KERN_WARNING
"Too much SLMs\n" );
953 CMDSET_TARG_LUN( slminquiry_cmd
, target
, lun
);
954 if (!acsicmd_nodma( slminquiry_cmd
, 0 )) {
956 printk( KERN_ERR
"SLM inquiry command timed out.\n" );
958 acsi_end_extstatus();
961 /* read status and header of return data */
962 if (!acsi_extstatus( SLMBuffer
, 6 ))
965 if (SLMBuffer
[1] != 2) { /* device type == printer? */
966 printk( KERN_ERR
"SLM inquiry returned device type != printer\n" );
972 if (!acsi_extstatus( SLMBuffer
, len
))
974 acsi_end_extstatus();
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 );
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
);
997 if (register_chrdev( ACSI_MAJOR
, "slm", &slm_fops
)) {
998 printk( KERN_ERR
"Unable to get major %d for ACSI SLM\n", ACSI_MAJOR
);
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" );
1007 BufferP
= SLMBuffer
;
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
);
1021 void acsi_attach_SLMs( int (*attach_func
)( int, int ) );
1023 int init_module(void)
1027 if ((err
= slm_init()))
1029 /* This calls attach_slm() for every target/lun where acsi.c detected a
1031 acsi_attach_SLMs( attach_slm
);
1035 void cleanup_module(void)
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
);