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/malloc.h>
69 #include <asm/pgtable.h>
70 #include <asm/system.h>
71 #include <asm/uaccess.h>
72 #include <asm/atarihw.h>
73 #include <asm/atariints.h>
74 #include <asm/atari_acsi.h>
75 #include <asm/atari_stdma.h>
76 #include <asm/atari_stram.h>
77 #include <asm/atari_SLM.h>
82 /* Define this if the page data are continuous in physical memory. That
83 * requires less reprogramming of the ST-DMA */
84 #define SLM_CONTINUOUS_DMA
86 /* Use continuous reprogramming of the ST-DMA counter register. This is
87 * --strictly speaking-- not allowed, Atari recommends not to look at the
88 * counter register while a DMA is going on. But I don't know if that applies
89 * only for reading the register, or also writing to it. Writing only works
90 * fine for me... The advantage is that the timing becomes absolutely
91 * uncritical: Just update each, say 200ms, the counter reg to its maximum,
92 * and the DMA will work until the status byte interrupt occurs.
94 #define SLM_CONT_CNT_REPROG
96 #define MAJOR_NR ACSI_MAJOR
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 unsigned wbusy
: 1; /* output part busy */
123 unsigned rbusy
: 1; /* 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 void 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
= { NULL
, NULL
, 0, 0, slm_test_ready
};
273 static struct file_operations slm_fops
= {
274 NULL
, /* lseek - default */
275 slm_read
, /* read - status reading */
276 slm_write
, /* write - printing data write */
277 NULL
, /* readdir - bad */
279 slm_ioctl
, /* ioctl */
283 slm_release
, /* release */
288 /* ---------------------------------------------------------------------- */
289 /* Status Functions */
292 static char *slm_errstr( int stat
)
298 if (stat
>= 0 && stat
< N_ERRORS
&& (p
= SLMErrors
[stat
]))
300 sprintf( str
, "unknown status 0x%02x", stat
);
305 static int slm_getstats( char *buffer
, int device
)
307 { int len
= 0, stat
, i
, w
, h
;
308 unsigned char buf
[256];
310 stat
= slm_mode_sense( device
, buf
, 0 );
311 if (IS_REAL_ERROR(stat
))
314 #define SHORTDATA(i) ((buf[i] << 8) | buf[i+1])
315 #define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off")
320 len
+= sprintf( buffer
+len
, "Status\t\t%s\n",
321 slm_errstr( stat
) );
322 len
+= sprintf( buffer
+len
, "Page Size\t%dx%d",
325 for( i
= 0; i
< N_STD_SIZES
; ++i
) {
326 if (w
== StdPageSize
[i
].w
&& h
== StdPageSize
[i
].h
)
330 len
+= sprintf( buffer
+len
, " (%s)", StdPageSize
[i
].name
);
331 buffer
[len
++] = '\n';
333 len
+= sprintf( buffer
+len
, "Top/Left Margin\t%d/%d\n",
334 SHORTDATA( 5 ), SHORTDATA( 7 ) );
335 len
+= sprintf( buffer
+len
, "Manual Feed\t%s\n",
336 BOOLDATA( 9, 0x01 ) );
337 len
+= sprintf( buffer
+len
, "Input Select\t%d\n",
339 len
+= sprintf( buffer
+len
, "Auto Select\t%s\n",
340 BOOLDATA( 9, 0x10 ) );
341 len
+= sprintf( buffer
+len
, "Prefeed Paper\t%s\n",
342 BOOLDATA( 9, 0x20 ) );
343 len
+= sprintf( buffer
+len
, "Thick Pixels\t%s\n",
344 BOOLDATA( 9, 0x40 ) );
345 len
+= sprintf( buffer
+len
, "H/V Resol.\t%d/%d dpi\n",
346 SHORTDATA( 12 ), SHORTDATA( 10 ) );
347 len
+= sprintf( buffer
+len
, "System Timeout\t%d\n",
349 len
+= sprintf( buffer
+len
, "Scan Time\t%d\n",
351 len
+= sprintf( buffer
+len
, "Page Count\t%d\n",
353 len
+= sprintf( buffer
+len
, "In/Out Cap.\t%d/%d\n",
354 SHORTDATA( 19 ), SHORTDATA( 21 ) );
355 len
+= sprintf( buffer
+len
, "Stagger Output\t%s\n",
356 BOOLDATA( 23, 0x01 ) );
357 len
+= sprintf( buffer
+len
, "Output Select\t%d\n",
358 (buf
[23] >> 1) & 7 );
359 len
+= sprintf( buffer
+len
, "Duplex Print\t%s\n",
360 BOOLDATA( 23, 0x10 ) );
361 len
+= sprintf( buffer
+len
, "Color Sep.\t%s\n",
362 BOOLDATA( 23, 0x20 ) );
368 static ssize_t
slm_read( struct file
*file
, char *buf
, size_t count
,
372 struct inode
*node
= file
->f_dentry
->d_inode
;
379 if (!(page
= __get_free_page( GFP_KERNEL
)))
382 length
= slm_getstats( (char *)page
, MINOR(node
->i_rdev
) );
387 if (file
->f_pos
>= length
) {
391 if (count
+ file
->f_pos
> length
)
392 count
= length
- file
->f_pos
;
393 end
= count
+ file
->f_pos
;
394 copy_to_user( buf
, (char *)page
+ file
->f_pos
, count
);
401 /* ---------------------------------------------------------------------- */
405 static void start_print( int device
)
407 { struct slm
*sip
= &slm_info
[device
];
412 stdma_lock( slm_interrupt
, NULL
);
414 CMDSET_TARG_LUN( slmprint_cmd
, sip
->target
, sip
->lun
);
416 paddr
= virt_to_phys( SLMBuffer
);
417 dma_cache_maintenance( paddr
, virt_to_phys(BufferP
)-paddr
, 1 );
421 dma_wd
.dma_mode_status
= 0x88;
424 /* send the command bytes except the last */
425 for( i
= 0; i
< 5; ++i
) {
426 DMA_LONG_WRITE( *cmd
++, 0x8a );
428 if (!acsi_wait_for_IRQ( HZ
/2 )) {
430 return; /* timeout */
433 /* last command byte */
434 DMA_LONG_WRITE( *cmd
++, 0x82 );
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;
441 /* program for 255*512 bytes and start DMA */
442 DMA_LONG_WRITE( SLM_DMA_AMOUNT
, 0x112 );
444 #ifndef SLM_CONT_CNT_REPROG
446 SLMEndAddr
= paddr
+ SLMSliceSize
+ SLM_DMA_INT_OFFSET
;
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
) );
458 /* Only called when an error happened or at the end of a page */
460 static void slm_interrupt(int irc
, void *data
, struct pt_regs
*fp
)
462 { unsigned long addr
;
466 addr
= get_dma_addr();
467 stat
= acsi_getstatus();
468 SLMError
= (stat
< 0) ? SLMSTAT_ACSITO
:
469 (addr
< virt_to_phys(BufferP
)) ? SLMSTAT_NOTALL
:
472 dma_wd
.dma_mode_status
= 0x80;
475 printk( "SLM: interrupt, addr=%#lx, error=%d\n", addr
, SLMError
);
478 wake_up( &print_wait
);
484 static void slm_test_ready( unsigned long dummy
)
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) );
492 printk( "SLM: reprogramming timer for %d jiffies, addr=%#lx\n",
493 DMA_TIME_FOR(0), get_dma_addr() );
496 #else /* !SLM_CONT_CNT_REPROG */
498 unsigned long flags
, addr
;
501 struct timeval start_tm
, end_tm
;
508 addr
= get_dma_addr();
509 if ((d
= SLMEndAddr
- addr
) > 0) {
510 restore_flags(flags
);
512 /* slice not yet finished, decide whether to start another timer or to
514 ti
= DMA_TIME_FOR( d
);
517 printk( "SLM: reprogramming timer for %d jiffies, rest %d bytes\n",
523 /* wait for desired end address to be reached */
525 do_gettimeofday( &start_tm
);
529 while( get_dma_addr() < SLMEndAddr
)
533 /* slice finished, start next one */
534 SLMCurAddr
+= SLMSliceSize
;
536 #ifdef SLM_CONTINUOUS_DMA
537 /* program for 255*512 bytes again */
538 dma_wd
.fdc_acces_seccount
= SLM_DMA_AMOUNT
;
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;
546 dma_wd
.dma_mode_status
= 0x192;
548 /* program for 255*512 bytes and start DMA */
549 DMA_LONG_WRITE( SLM_DMA_AMOUNT
, 0x112 );
552 restore_flags(flags
);
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
);
564 printk( "SLM: didn't wait (!)\n" );
567 if ((unsigned char *)PTOV( SLMCurAddr
+ SLMSliceSize
) >= BufferP
) {
568 /* will be last slice, no timer necessary */
570 printk( "SLM: CurAddr=%#lx EndAddr=%#lx last slice -> no timer\n",
571 SLMCurAddr
, SLMEndAddr
);
576 SLMEndAddr
= SLMCurAddr
+ SLMSliceSize
+ SLM_DMA_INT_OFFSET
;
577 START_TIMER( DMA_TIME_FOR( SLMSliceSize
));
579 printk( "SLM: CurAddr=%#lx EndAddr=%#lx timer=%ld\n",
580 SLMCurAddr
, SLMEndAddr
, DMA_TIME_FOR( SLMSliceSize
) );
583 #endif /* SLM_CONT_CNT_REPROG */
587 static void set_dma_addr( unsigned long paddr
)
589 { unsigned long flags
;
593 dma_wd
.dma_lo
= (unsigned char)paddr
;
596 dma_wd
.dma_md
= (unsigned char)paddr
;
599 if (ATARIHW_PRESENT( EXTD_DMA
))
600 st_dma_ext_dmahi
= (unsigned short)paddr
;
602 dma_wd
.dma_hi
= (unsigned char)paddr
;
604 restore_flags(flags
);
608 static unsigned long get_dma_addr( void )
610 { unsigned long addr
;
612 addr
= dma_wd
.dma_lo
& 0xff;
614 addr
|= (dma_wd
.dma_md
& 0xff) << 8;
616 addr
|= (dma_wd
.dma_hi
& 0xff) << 16;
623 static ssize_t
slm_write( struct file
*file
, const char *buf
, size_t count
,
627 struct inode
*node
= file
->f_dentry
->d_inode
;
628 int device
= MINOR( node
->i_rdev
);
631 while( SLMState
== PRINTING
||
632 (SLMState
== FILLING
&& SLMBufOwner
!= device
) ) {
633 interruptible_sleep_on( &slm_wait
);
634 if (signal_pending(current
))
635 return( -ERESTARTSYS
);
637 if (SLMState
== IDLE
) {
638 /* first data of page: get current page size */
639 if (slm_get_pagesize( device
, &w
, &h
))
642 if (BufferSize
> SLM_BUFFER_SIZE
)
646 SLMBufOwner
= device
;
650 filled
= BufferP
- SLMBuffer
;
651 if (filled
+ n
> BufferSize
)
652 n
= BufferSize
- filled
;
654 copy_from_user( BufferP
, buf
, n
);
658 if (filled
== BufferSize
) {
659 /* Check the paper size again! The user may have switched it in the
660 * time between starting the data and finishing them. Would end up in
661 * a trashy page... */
662 if (slm_get_pagesize( device
, &w
, &h
))
664 if (BufferSize
!= w
*h
/8) {
665 printk( KERN_NOTICE
"slm%d: page size changed while printing\n",
671 /* choose a slice size that is a multiple of the line size */
672 #ifndef SLM_CONT_CNT_REPROG
673 SLMSliceSize
= SLM_SLICE_SIZE(w
);
676 start_print( device
);
677 sleep_on( &print_wait
);
678 if (SLMError
&& IS_REAL_ERROR(SLMError
)) {
679 printk( KERN_ERR
"slm%d: %s\n", device
, slm_errstr(SLMError
) );
685 wake_up_interruptible( &slm_wait
);
692 /* ---------------------------------------------------------------------- */
693 /* ioctl Functions */
696 static int slm_ioctl( struct inode
*inode
, struct file
*file
,
697 unsigned int cmd
, unsigned long arg
)
699 { int device
= MINOR( inode
->i_rdev
), err
;
701 /* I can think of setting:
706 * but haven't implemented that yet :-)
707 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
711 case SLMIORESET
: /* reset buffer, i.e. empty the buffer */
712 if (!(file
->f_mode
& 2))
714 if (SLMState
== PRINTING
)
718 wake_up_interruptible( &slm_wait
);
721 case SLMIOGSTAT
: { /* get status */
725 stat
= slm_req_sense( device
);
727 str
= slm_errstr( stat
);
729 (long *)&((struct SLM_status
*)arg
)->stat
))
731 copy_to_user( ((struct SLM_status
*)arg
)->str
, str
,
737 case SLMIOGPSIZE
: { /* get paper size */
740 err
= verify_area( VERIFY_WRITE
, (long *)arg
,
741 sizeof(struct SLM_paper_size
) );
742 if (err
) return( err
);
744 if ((err
= slm_get_pagesize( device
, &w
, &h
))) return( err
);
746 if (put_user(w
, (long *)&((struct SLM_paper_size
*)arg
)->width
))
748 if (put_user(h
, (long *)&((struct SLM_paper_size
*)arg
)->height
))
753 case SLMIOGMFEED
: /* get manual feed */
756 case SLMIOSPSIZE
: /* set paper size */
759 case SLMIOSMFEED
: /* set manual feed */
767 /* ---------------------------------------------------------------------- */
768 /* Opening and Closing */
771 static int slm_open( struct inode
*inode
, struct file
*file
)
776 device
= MINOR(inode
->i_rdev
);
777 if (device
>= N_SLM_Printers
)
779 sip
= &slm_info
[device
];
781 if (file
->f_mode
& 2) {
782 /* open for writing is exclusive */
787 if (file
->f_mode
& 1) {
788 /* open for writing is exclusive */
798 static int slm_release( struct inode
*inode
, struct file
*file
)
803 device
= MINOR(inode
->i_rdev
);
804 sip
= &slm_info
[device
];
806 if (file
->f_mode
& 2)
808 if (file
->f_mode
& 1)
815 /* ---------------------------------------------------------------------- */
816 /* ACSI Primitives for the SLM */
819 static int slm_req_sense( int device
)
822 struct slm
*sip
= &slm_info
[device
];
824 stdma_lock( NULL
, NULL
);
826 CMDSET_TARG_LUN( slmreqsense_cmd
, sip
->target
, sip
->lun
);
827 if (!acsicmd_nodma( slmreqsense_cmd
, 0 ) ||
828 (stat
= acsi_getstatus()) < 0)
839 static int slm_mode_sense( int device
, char *buffer
, int abs_flag
)
841 { unsigned char stat
, len
;
843 struct slm
*sip
= &slm_info
[device
];
845 stdma_lock( NULL
, NULL
);
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 )) {
854 if (!acsi_extstatus( &stat
, 1 )) {
855 acsi_end_extstatus();
860 if (!acsi_extstatus( &len
, 1 )) {
861 acsi_end_extstatus();
866 if (!acsi_extstatus( buffer
+1, len
)) {
867 acsi_end_extstatus();
872 acsi_end_extstatus();
883 /* currently unused */
884 static int slm_mode_select( int device
, char *buffer
, int len
,
888 struct slm
*sip
= &slm_info
[device
];
890 stdma_lock( NULL
, NULL
);
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 )) {
900 unsigned char c
= len
;
901 if (!acsi_extcmd( &c
, 1 )) {
905 if (!acsi_extcmd( buffer
, len
)) {
911 stat
= acsi_getstatus();
912 rv
= (stat
< 0 ? SLMSTAT_ACSITO
: stat
);
922 static int slm_get_pagesize( int device
, int *w
, int *h
)
927 stat
= slm_mode_sense( device
, buf
, 0 );
931 if (stat
!= SLMSTAT_OK
)
934 *w
= (buf
[3] << 8) | buf
[4];
935 *h
= (buf
[1] << 8) | buf
[2];
940 /* ---------------------------------------------------------------------- */
944 int attach_slm( int target
, int lun
)
946 { static int did_register
= 0;
949 if (N_SLM_Printers
>= MAX_SLM
) {
950 printk( KERN_WARNING
"Too much SLMs\n" );
956 CMDSET_TARG_LUN( slminquiry_cmd
, target
, lun
);
957 if (!acsicmd_nodma( slminquiry_cmd
, 0 )) {
959 printk( KERN_ERR
"SLM inquiry command timed out.\n" );
961 acsi_end_extstatus();
964 /* read status and header of return data */
965 if (!acsi_extstatus( SLMBuffer
, 6 ))
968 if (SLMBuffer
[1] != 2) { /* device type == printer? */
969 printk( KERN_ERR
"SLM inquiry returned device type != printer\n" );
975 if (!acsi_extstatus( SLMBuffer
, len
))
977 acsi_end_extstatus();
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;
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
);
1000 if (register_chrdev( MAJOR_NR
, "slm", &slm_fops
)) {
1001 printk( KERN_ERR
"Unable to get major %d for ACSI SLM\n", MAJOR_NR
);
1005 if (!(SLMBuffer
= atari_stram_alloc( SLM_BUFFER_SIZE
, NULL
, "SLM" ))) {
1006 printk( KERN_ERR
"Unable to get SLM ST-Ram buffer.\n" );
1007 unregister_chrdev( MAJOR_NR
, "slm" );
1010 BufferP
= SLMBuffer
;
1019 void acsi_attach_SLMs( int (*attach_func
)( int, int ) );
1021 int init_module(void)
1025 if ((err
= slm_init()))
1027 /* This calls attach_slm() for every target/lun where acsi.c detected a
1029 acsi_attach_SLMs( attach_slm
);
1033 void cleanup_module(void)
1035 if (unregister_chrdev( MAJOR_NR
, "slm" ) != 0)
1036 printk( KERN_ERR
"acsi_slm: cleanup_module failed\n");
1037 atari_stram_free( SLMBuffer
);