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/smp_lock.h>
70 #include <asm/pgtable.h>
71 #include <asm/system.h>
72 #include <asm/uaccess.h>
73 #include <asm/atarihw.h>
74 #include <asm/atariints.h>
75 #include <asm/atari_acsi.h>
76 #include <asm/atari_stdma.h>
77 #include <asm/atari_stram.h>
78 #include <asm/atari_SLM.h>
83 /* Define this if the page data are continuous in physical memory. That
84 * requires less reprogramming of the ST-DMA */
85 #define SLM_CONTINUOUS_DMA
87 /* Use continuous reprogramming of the ST-DMA counter register. This is
88 * --strictly speaking-- not allowed, Atari recommends not to look at the
89 * counter register while a DMA is going on. But I don't know if that applies
90 * only for reading the register, or also writing to it. Writing only works
91 * fine for me... The advantage is that the timing becomes absolutely
92 * uncritical: Just update each, say 200ms, the counter reg to its maximum,
93 * and the DMA will work until the status byte interrupt occurs.
95 #define SLM_CONT_CNT_REPROG
97 #define CMDSET_TARG_LUN(cmd,targ,lun) \
99 cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \
100 cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \
103 #define START_TIMER(to) mod_timer(&slm_timer, jiffies + (to))
104 #define STOP_TIMER() del_timer(&slm_timer)
107 static char slmreqsense_cmd
[6] = { 0x03, 0, 0, 0, 0, 0 };
108 static char slmprint_cmd
[6] = { 0x0a, 0, 0, 0, 0, 0 };
109 static char slminquiry_cmd
[6] = { 0x12, 0, 0, 0, 0, 0x80 };
110 static char slmmsense_cmd
[6] = { 0x1a, 0, 0, 0, 255, 0 };
112 static char slmmselect_cmd
[6] = { 0x15, 0, 0, 0, 0, 0 };
119 unsigned target
; /* target number */
120 unsigned lun
; /* LUN in target controller */
121 atomic_t wr_ok
; /* set to 0 if output part busy */
122 atomic_t rd_ok
; /* set to 0 if status part busy */
125 int N_SLM_Printers
= 0;
128 static unsigned char *SLMBuffer
; /* start of buffer */
129 static unsigned char *BufferP
; /* current position in buffer */
130 static int BufferSize
; /* length of buffer for page size */
132 typedef enum { IDLE
, FILLING
, PRINTING
} SLMSTATE
;
133 static SLMSTATE SLMState
;
134 static int SLMBufOwner
; /* SLM# currently using the buffer */
137 #ifndef SLM_CONT_CNT_REPROG
138 static unsigned long SLMCurAddr
; /* current base addr of DMA chunk */
139 static unsigned long SLMEndAddr
; /* expected end addr */
140 static unsigned long SLMSliceSize
; /* size of one DMA chunk */
145 static DECLARE_WAIT_QUEUE_HEAD(slm_wait
); /* waiting for buffer */
146 static DECLARE_WAIT_QUEUE_HEAD(print_wait
); /* waiting for printing finished */
149 #define SLMSTAT_OK 0x00
150 #define SLMSTAT_ORNERY 0x02
151 #define SLMSTAT_TONER 0x03
152 #define SLMSTAT_WARMUP 0x04
153 #define SLMSTAT_PAPER 0x05
154 #define SLMSTAT_DRUM 0x06
155 #define SLMSTAT_INJAM 0x07
156 #define SLMSTAT_THRJAM 0x08
157 #define SLMSTAT_OUTJAM 0x09
158 #define SLMSTAT_COVER 0x0a
159 #define SLMSTAT_FUSER 0x0b
160 #define SLMSTAT_IMAGER 0x0c
161 #define SLMSTAT_MOTOR 0x0d
162 #define SLMSTAT_VIDEO 0x0e
163 #define SLMSTAT_SYSTO 0x10
164 #define SLMSTAT_OPCODE 0x12
165 #define SLMSTAT_DEVNUM 0x15
166 #define SLMSTAT_PARAM 0x1a
167 #define SLMSTAT_ACSITO 0x1b /* driver defined */
168 #define SLMSTAT_NOTALL 0x1c /* driver defined */
170 static char *SLMErrors
[] = {
171 /* 0x00 */ "OK and ready",
173 /* 0x02 */ "ornery printer",
174 /* 0x03 */ "toner empty",
175 /* 0x04 */ "warming up",
176 /* 0x05 */ "paper empty",
177 /* 0x06 */ "drum empty",
178 /* 0x07 */ "input jam",
179 /* 0x08 */ "through jam",
180 /* 0x09 */ "output jam",
181 /* 0x0a */ "cover open",
182 /* 0x0b */ "fuser malfunction",
183 /* 0x0c */ "imager malfunction",
184 /* 0x0d */ "motor malfunction",
185 /* 0x0e */ "video malfunction",
187 /* 0x10 */ "printer system timeout",
189 /* 0x12 */ "invalid operation code",
192 /* 0x15 */ "invalid device number",
197 /* 0x1a */ "invalid parameter list",
198 /* 0x1b */ "ACSI timeout",
199 /* 0x1c */ "not all printed"
202 #define N_ERRORS (sizeof(SLMErrors)/sizeof(*SLMErrors))
204 /* real (driver caused) error? */
205 #define IS_REAL_ERROR(x) (x > 0x10)
212 { "Letter", 2400, 3180 },
213 { "Legal", 2400, 4080 },
214 { "A4", 2336, 3386 },
218 #define N_STD_SIZES (sizeof(StdPageSize)/sizeof(*StdPageSize))
220 #define SLM_BUFFER_SIZE (2336*3386/8) /* A4 for now */
221 #define SLM_DMA_AMOUNT 255 /* #sectors to program the DMA for */
223 #ifdef SLM_CONTINUOUS_DMA
224 # define SLM_DMA_INT_OFFSET 0 /* DMA goes until seccnt 0, no offs */
225 # define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */
226 # define SLM_SLICE_SIZE(w) (255*512)
228 # define SLM_DMA_INT_OFFSET 32 /* 32 Byte ST-DMA FIFO */
229 # define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */
230 # define SLM_SLICE_SIZE(w) ((254*512)/(w/8)*(w/8))
233 /* calculate the number of jiffies to wait for 'n' bytes */
234 #ifdef SLM_CONT_CNT_REPROG
235 #define DMA_TIME_FOR(n) 50
236 #define DMA_STARTUP_TIME 0
238 #define DMA_TIME_FOR(n) (n/1400-1)
239 #define DMA_STARTUP_TIME 650
242 /***************************** Prototypes *****************************/
244 static char *slm_errstr( int stat
);
245 static int slm_getstats( char *buffer
, int device
);
246 static ssize_t
slm_read( struct file
* file
, char *buf
, size_t count
, loff_t
248 static void start_print( int device
);
249 static irqreturn_t
slm_interrupt(int irc
, void *data
);
250 static void slm_test_ready( unsigned long dummy
);
251 static void set_dma_addr( unsigned long paddr
);
252 static unsigned long get_dma_addr( void );
253 static ssize_t
slm_write( struct file
*file
, const char *buf
, size_t count
,
255 static int slm_ioctl( struct inode
*inode
, struct file
*file
, unsigned int
256 cmd
, unsigned long arg
);
257 static int slm_open( struct inode
*inode
, struct file
*file
);
258 static int slm_release( struct inode
*inode
, struct file
*file
);
259 static int slm_req_sense( int device
);
260 static int slm_mode_sense( int device
, char *buffer
, int abs_flag
);
262 static int slm_mode_select( int device
, char *buffer
, int len
, int
265 static int slm_get_pagesize( int device
, int *w
, int *h
);
267 /************************* End of Prototypes **************************/
270 static DEFINE_TIMER(slm_timer
, slm_test_ready
, 0, 0);
272 static const struct file_operations slm_fops
= {
273 .owner
= THIS_MODULE
,
278 .release
= slm_release
,
282 /* ---------------------------------------------------------------------- */
283 /* Status Functions */
286 static char *slm_errstr( int stat
)
292 if (stat
>= 0 && stat
< N_ERRORS
&& (p
= SLMErrors
[stat
]))
294 sprintf( str
, "unknown status 0x%02x", stat
);
299 static int slm_getstats( char *buffer
, int device
)
301 { int len
= 0, stat
, i
, w
, h
;
302 unsigned char buf
[256];
304 stat
= slm_mode_sense( device
, buf
, 0 );
305 if (IS_REAL_ERROR(stat
))
308 #define SHORTDATA(i) ((buf[i] << 8) | buf[i+1])
309 #define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off")
314 len
+= sprintf( buffer
+len
, "Status\t\t%s\n",
315 slm_errstr( stat
) );
316 len
+= sprintf( buffer
+len
, "Page Size\t%dx%d",
319 for( i
= 0; i
< N_STD_SIZES
; ++i
) {
320 if (w
== StdPageSize
[i
].w
&& h
== StdPageSize
[i
].h
)
324 len
+= sprintf( buffer
+len
, " (%s)", StdPageSize
[i
].name
);
325 buffer
[len
++] = '\n';
327 len
+= sprintf( buffer
+len
, "Top/Left Margin\t%d/%d\n",
328 SHORTDATA( 5 ), SHORTDATA( 7 ) );
329 len
+= sprintf( buffer
+len
, "Manual Feed\t%s\n",
330 BOOLDATA( 9, 0x01 ) );
331 len
+= sprintf( buffer
+len
, "Input Select\t%d\n",
333 len
+= sprintf( buffer
+len
, "Auto Select\t%s\n",
334 BOOLDATA( 9, 0x10 ) );
335 len
+= sprintf( buffer
+len
, "Prefeed Paper\t%s\n",
336 BOOLDATA( 9, 0x20 ) );
337 len
+= sprintf( buffer
+len
, "Thick Pixels\t%s\n",
338 BOOLDATA( 9, 0x40 ) );
339 len
+= sprintf( buffer
+len
, "H/V Resol.\t%d/%d dpi\n",
340 SHORTDATA( 12 ), SHORTDATA( 10 ) );
341 len
+= sprintf( buffer
+len
, "System Timeout\t%d\n",
343 len
+= sprintf( buffer
+len
, "Scan Time\t%d\n",
345 len
+= sprintf( buffer
+len
, "Page Count\t%d\n",
347 len
+= sprintf( buffer
+len
, "In/Out Cap.\t%d/%d\n",
348 SHORTDATA( 19 ), SHORTDATA( 21 ) );
349 len
+= sprintf( buffer
+len
, "Stagger Output\t%s\n",
350 BOOLDATA( 23, 0x01 ) );
351 len
+= sprintf( buffer
+len
, "Output Select\t%d\n",
352 (buf
[23] >> 1) & 7 );
353 len
+= sprintf( buffer
+len
, "Duplex Print\t%s\n",
354 BOOLDATA( 23, 0x10 ) );
355 len
+= sprintf( buffer
+len
, "Color Sep.\t%s\n",
356 BOOLDATA( 23, 0x20 ) );
362 static ssize_t
slm_read( struct file
*file
, char *buf
, size_t count
,
366 struct inode
*node
= file
->f_path
.dentry
->d_inode
;
371 if (!(page
= __get_free_page( GFP_KERNEL
)))
374 length
= slm_getstats( (char *)page
, iminor(node
) );
379 if (file
->f_pos
>= length
) {
383 if (count
+ file
->f_pos
> length
)
384 count
= length
- file
->f_pos
;
385 end
= count
+ file
->f_pos
;
386 if (copy_to_user(buf
, (char *)page
+ file
->f_pos
, count
)) {
391 out
: free_page( page
);
396 /* ---------------------------------------------------------------------- */
400 static void start_print( int device
)
402 { struct slm
*sip
= &slm_info
[device
];
407 stdma_lock( slm_interrupt
, NULL
);
409 CMDSET_TARG_LUN( slmprint_cmd
, sip
->target
, sip
->lun
);
411 paddr
= virt_to_phys( SLMBuffer
);
412 dma_cache_maintenance( paddr
, virt_to_phys(BufferP
)-paddr
, 1 );
416 dma_wd
.dma_mode_status
= 0x88;
419 /* send the command bytes except the last */
420 for( i
= 0; i
< 5; ++i
) {
421 DMA_LONG_WRITE( *cmd
++, 0x8a );
423 if (!acsi_wait_for_IRQ( HZ
/2 )) {
425 return; /* timeout */
428 /* last command byte */
429 DMA_LONG_WRITE( *cmd
++, 0x82 );
431 /* set DMA address */
432 set_dma_addr( paddr
);
433 /* program DMA for write and select sector counter reg */
434 dma_wd
.dma_mode_status
= 0x192;
436 /* program for 255*512 bytes and start DMA */
437 DMA_LONG_WRITE( SLM_DMA_AMOUNT
, 0x112 );
439 #ifndef SLM_CONT_CNT_REPROG
441 SLMEndAddr
= paddr
+ SLMSliceSize
+ SLM_DMA_INT_OFFSET
;
443 START_TIMER( DMA_STARTUP_TIME
+ DMA_TIME_FOR( SLMSliceSize
));
444 #if !defined(SLM_CONT_CNT_REPROG) && defined(DEBUG)
445 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
446 SLMCurAddr
, SLMEndAddr
, DMA_TIME_FOR( SLMSliceSize
) );
453 /* Only called when an error happened or at the end of a page */
455 static irqreturn_t
slm_interrupt(int irc
, void *data
)
457 { unsigned long addr
;
461 addr
= get_dma_addr();
462 stat
= acsi_getstatus();
463 SLMError
= (stat
< 0) ? SLMSTAT_ACSITO
:
464 (addr
< virt_to_phys(BufferP
)) ? SLMSTAT_NOTALL
:
467 dma_wd
.dma_mode_status
= 0x80;
470 printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr
, SLMError
);
473 wake_up( &print_wait
);
480 static void slm_test_ready( unsigned long dummy
)
483 #ifdef SLM_CONT_CNT_REPROG
484 /* program for 255*512 bytes again */
485 dma_wd
.fdc_acces_seccount
= SLM_DMA_AMOUNT
;
486 START_TIMER( DMA_TIME_FOR(0) );
488 printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
489 DMA_TIME_FOR(0), get_dma_addr() );
492 #else /* !SLM_CONT_CNT_REPROG */
494 unsigned long flags
, addr
;
497 struct timeval start_tm
, end_tm
;
501 local_irq_save(flags
);
503 addr
= get_dma_addr();
504 if ((d
= SLMEndAddr
- addr
) > 0) {
505 local_irq_restore(flags
);
507 /* slice not yet finished, decide whether to start another timer or to
509 ti
= DMA_TIME_FOR( d
);
512 printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
518 /* wait for desired end address to be reached */
520 do_gettimeofday( &start_tm
);
524 while( get_dma_addr() < SLMEndAddr
)
528 /* slice finished, start next one */
529 SLMCurAddr
+= SLMSliceSize
;
531 #ifdef SLM_CONTINUOUS_DMA
532 /* program for 255*512 bytes again */
533 dma_wd
.fdc_acces_seccount
= SLM_DMA_AMOUNT
;
536 * add 2 bytes for the ones in the SLM controller FIFO! */
537 set_dma_addr( SLMCurAddr
+ 2 );
538 /* toggle DMA to write and select sector counter reg */
539 dma_wd
.dma_mode_status
= 0x92;
541 dma_wd
.dma_mode_status
= 0x192;
543 /* program for 255*512 bytes and start DMA */
544 DMA_LONG_WRITE( SLM_DMA_AMOUNT
, 0x112 );
547 local_irq_restore(flags
);
552 do_gettimeofday( &end_tm
);
553 ms
= (end_tm
.tv_sec
*1000000+end_tm
.tv_usec
) -
554 (start_tm
.tv_sec
*1000000+start_tm
.tv_usec
);
555 printk( "SLM: did %ld.%ld ms busy waiting for %d bytes\n",
556 ms
/1000, ms
%1000, d
);
559 printk( "SLM: didn't wait (!)\n" );
562 if ((unsigned char *)PTOV( SLMCurAddr
+ SLMSliceSize
) >= BufferP
) {
563 /* will be last slice, no timer necessary */
565 printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
566 SLMCurAddr
, SLMEndAddr
);
571 SLMEndAddr
= SLMCurAddr
+ SLMSliceSize
+ SLM_DMA_INT_OFFSET
;
572 START_TIMER( DMA_TIME_FOR( SLMSliceSize
));
574 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
575 SLMCurAddr
, SLMEndAddr
, DMA_TIME_FOR( SLMSliceSize
) );
578 #endif /* SLM_CONT_CNT_REPROG */
582 static void set_dma_addr( unsigned long paddr
)
584 { unsigned long flags
;
586 local_irq_save(flags
);
587 dma_wd
.dma_lo
= (unsigned char)paddr
;
590 dma_wd
.dma_md
= (unsigned char)paddr
;
593 if (ATARIHW_PRESENT( EXTD_DMA
))
594 st_dma_ext_dmahi
= (unsigned short)paddr
;
596 dma_wd
.dma_hi
= (unsigned char)paddr
;
598 local_irq_restore(flags
);
602 static unsigned long get_dma_addr( void )
604 { unsigned long addr
;
606 addr
= dma_wd
.dma_lo
& 0xff;
608 addr
|= (dma_wd
.dma_md
& 0xff) << 8;
610 addr
|= (dma_wd
.dma_hi
& 0xff) << 16;
617 static ssize_t
slm_write( struct file
*file
, const char *buf
, size_t count
,
621 struct inode
*node
= file
->f_path
.dentry
->d_inode
;
622 int device
= iminor(node
);
625 while( SLMState
== PRINTING
||
626 (SLMState
== FILLING
&& SLMBufOwner
!= device
) ) {
627 interruptible_sleep_on( &slm_wait
);
628 if (signal_pending(current
))
629 return( -ERESTARTSYS
);
631 if (SLMState
== IDLE
) {
632 /* first data of page: get current page size */
633 if (slm_get_pagesize( device
, &w
, &h
))
636 if (BufferSize
> SLM_BUFFER_SIZE
)
640 SLMBufOwner
= device
;
644 filled
= BufferP
- SLMBuffer
;
645 if (filled
+ n
> BufferSize
)
646 n
= BufferSize
- filled
;
648 if (copy_from_user(BufferP
, buf
, n
))
653 if (filled
== BufferSize
) {
654 /* Check the paper size again! The user may have switched it in the
655 * time between starting the data and finishing them. Would end up in
656 * a trashy page... */
657 if (slm_get_pagesize( device
, &w
, &h
))
659 if (BufferSize
!= w
*h
/8) {
660 printk( KERN_NOTICE
"slm%d: page size changed while printing\n",
666 /* choose a slice size that is a multiple of the line size */
667 #ifndef SLM_CONT_CNT_REPROG
668 SLMSliceSize
= SLM_SLICE_SIZE(w
);
671 start_print( device
);
672 sleep_on( &print_wait
);
673 if (SLMError
&& IS_REAL_ERROR(SLMError
)) {
674 printk( KERN_ERR
"slm%d: %s\n", device
, slm_errstr(SLMError
) );
680 wake_up_interruptible( &slm_wait
);
687 /* ---------------------------------------------------------------------- */
688 /* ioctl Functions */
691 static int slm_ioctl( struct inode
*inode
, struct file
*file
,
692 unsigned int cmd
, unsigned long arg
)
694 { int device
= iminor(inode
), err
;
696 /* I can think of setting:
701 * but haven't implemented that yet :-)
702 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
706 case SLMIORESET
: /* reset buffer, i.e. empty the buffer */
707 if (!(file
->f_mode
& 2))
709 if (SLMState
== PRINTING
)
713 wake_up_interruptible( &slm_wait
);
716 case SLMIOGSTAT
: { /* get status */
720 stat
= slm_req_sense( device
);
722 str
= slm_errstr( stat
);
724 (long *)&((struct SLM_status
*)arg
)->stat
))
726 if (copy_to_user( ((struct SLM_status
*)arg
)->str
, str
,
733 case SLMIOGPSIZE
: { /* get paper size */
736 if ((err
= slm_get_pagesize( device
, &w
, &h
))) return( err
);
738 if (put_user(w
, (long *)&((struct SLM_paper_size
*)arg
)->width
))
740 if (put_user(h
, (long *)&((struct SLM_paper_size
*)arg
)->height
))
745 case SLMIOGMFEED
: /* get manual feed */
748 case SLMIOSPSIZE
: /* set paper size */
751 case SLMIOSMFEED
: /* set manual feed */
759 /* ---------------------------------------------------------------------- */
760 /* Opening and Closing */
763 static int slm_open( struct inode
*inode
, struct file
*file
)
768 device
= iminor(inode
);
769 if (device
>= N_SLM_Printers
)
771 sip
= &slm_info
[device
];
773 if (file
->f_mode
& 2) {
774 /* open for writing is exclusive */
775 if ( !atomic_dec_and_test(&sip
->wr_ok
) ) {
776 atomic_inc(&sip
->wr_ok
);
780 if (file
->f_mode
& 1) {
781 /* open for reading is exclusive */
782 if ( !atomic_dec_and_test(&sip
->rd_ok
) ) {
783 atomic_inc(&sip
->rd_ok
);
792 static int slm_release( struct inode
*inode
, struct file
*file
)
797 device
= iminor(inode
);
798 sip
= &slm_info
[device
];
800 if (file
->f_mode
& 2)
801 atomic_inc( &sip
->wr_ok
);
802 if (file
->f_mode
& 1)
803 atomic_inc( &sip
->rd_ok
);
809 /* ---------------------------------------------------------------------- */
810 /* ACSI Primitives for the SLM */
813 static int slm_req_sense( int device
)
816 struct slm
*sip
= &slm_info
[device
];
818 stdma_lock( NULL
, NULL
);
820 CMDSET_TARG_LUN( slmreqsense_cmd
, sip
->target
, sip
->lun
);
821 if (!acsicmd_nodma( slmreqsense_cmd
, 0 ) ||
822 (stat
= acsi_getstatus()) < 0)
833 static int slm_mode_sense( int device
, char *buffer
, int abs_flag
)
835 { unsigned char stat
, len
;
837 struct slm
*sip
= &slm_info
[device
];
839 stdma_lock( NULL
, NULL
);
841 CMDSET_TARG_LUN( slmmsense_cmd
, sip
->target
, sip
->lun
);
842 slmmsense_cmd
[5] = abs_flag
? 0x80 : 0;
843 if (!acsicmd_nodma( slmmsense_cmd
, 0 )) {
848 if (!acsi_extstatus( &stat
, 1 )) {
849 acsi_end_extstatus();
854 if (!acsi_extstatus( &len
, 1 )) {
855 acsi_end_extstatus();
860 if (!acsi_extstatus( buffer
+1, len
)) {
861 acsi_end_extstatus();
866 acsi_end_extstatus();
877 /* currently unused */
878 static int slm_mode_select( int device
, char *buffer
, int len
,
882 struct slm
*sip
= &slm_info
[device
];
884 stdma_lock( NULL
, NULL
);
886 CMDSET_TARG_LUN( slmmselect_cmd
, sip
->target
, sip
->lun
);
887 slmmselect_cmd
[5] = default_flag
? 0x80 : 0;
888 if (!acsicmd_nodma( slmmselect_cmd
, 0 )) {
894 unsigned char c
= len
;
895 if (!acsi_extcmd( &c
, 1 )) {
899 if (!acsi_extcmd( buffer
, len
)) {
905 stat
= acsi_getstatus();
906 rv
= (stat
< 0 ? SLMSTAT_ACSITO
: stat
);
916 static int slm_get_pagesize( int device
, int *w
, int *h
)
921 stat
= slm_mode_sense( device
, buf
, 0 );
925 if (stat
!= SLMSTAT_OK
)
928 *w
= (buf
[3] << 8) | buf
[4];
929 *h
= (buf
[1] << 8) | buf
[2];
934 /* ---------------------------------------------------------------------- */
938 int attach_slm( int target
, int lun
)
940 { static int did_register
;
943 if (N_SLM_Printers
>= MAX_SLM
) {
944 printk( KERN_WARNING
"Too much SLMs\n" );
950 CMDSET_TARG_LUN( slminquiry_cmd
, target
, lun
);
951 if (!acsicmd_nodma( slminquiry_cmd
, 0 )) {
953 printk( KERN_ERR
"SLM inquiry command timed out.\n" );
955 acsi_end_extstatus();
958 /* read status and header of return data */
959 if (!acsi_extstatus( SLMBuffer
, 6 ))
962 if (SLMBuffer
[1] != 2) { /* device type == printer? */
963 printk( KERN_ERR
"SLM inquiry returned device type != printer\n" );
969 if (!acsi_extstatus( SLMBuffer
, len
))
971 acsi_end_extstatus();
978 slm_info
[N_SLM_Printers
].target
= target
;
979 slm_info
[N_SLM_Printers
].lun
= lun
;
980 atomic_set(&slm_info
[N_SLM_Printers
].wr_ok
, 1 );
981 atomic_set(&slm_info
[N_SLM_Printers
].rd_ok
, 1 );
983 printk( KERN_INFO
" Printer: %s\n", SLMBuffer
);
984 printk( KERN_INFO
"Detected slm%d at id %d lun %d\n",
985 N_SLM_Printers
, target
, lun
);
994 if (register_chrdev( ACSI_MAJOR
, "slm", &slm_fops
)) {
995 printk( KERN_ERR
"Unable to get major %d for ACSI SLM\n", ACSI_MAJOR
);
999 if (!(SLMBuffer
= atari_stram_alloc( SLM_BUFFER_SIZE
, "SLM" ))) {
1000 printk( KERN_ERR
"Unable to get SLM ST-Ram buffer.\n" );
1001 unregister_chrdev( ACSI_MAJOR
, "slm" );
1004 BufferP
= SLMBuffer
;
1013 void acsi_attach_SLMs( int (*attach_func
)( int, int ) );
1015 int init_module(void)
1019 if ((err
= slm_init()))
1021 /* This calls attach_slm() for every target/lun where acsi.c detected a
1023 acsi_attach_SLMs( attach_slm
);
1027 void cleanup_module(void)
1029 if (unregister_chrdev( ACSI_MAJOR
, "slm" ) != 0)
1030 printk( KERN_ERR
"acsi_slm: cleanup_module failed\n");
1031 atari_stram_free( SLMBuffer
);