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 MAJOR_NR ACSI_MAJOR
100 #define CMDSET_TARG_LUN(cmd,targ,lun) \
102 cmd[0] = (cmd[0] & ~0xe0) | (targ)<<5; \
103 cmd[1] = (cmd[1] & ~0xe0) | (lun)<<5; \
106 #define START_TIMER(to) mod_timer(&slm_timer, jiffies + (to))
107 #define STOP_TIMER() del_timer(&slm_timer)
110 static char slmreqsense_cmd[6] = { 0x03, 0, 0, 0, 0, 0 };
111 static char slmprint_cmd[6] = { 0x0a, 0, 0, 0, 0, 0 };
112 static char slminquiry_cmd[6] = { 0x12, 0, 0, 0, 0, 0x80 };
113 static char slmmsense_cmd[6] = { 0x1a, 0, 0, 0, 255, 0 };
115 static char slmmselect_cmd[6] = { 0x15, 0, 0, 0, 0, 0 };
122 unsigned target; /* target number */
123 unsigned lun; /* LUN in target controller */
124 unsigned wbusy : 1; /* output part busy */
125 unsigned rbusy : 1; /* status part busy */
128 int N_SLM_Printers = 0;
131 static unsigned char *SLMBuffer; /* start of buffer */
132 static unsigned char *BufferP; /* current position in buffer */
133 static int BufferSize; /* length of buffer for page size */
135 typedef enum { IDLE, FILLING, PRINTING } SLMSTATE;
136 static SLMSTATE SLMState;
137 static int SLMBufOwner; /* SLM# currently using the buffer */
140 #ifndef SLM_CONT_CNT_REPROG
141 static unsigned long SLMCurAddr; /* current base addr of DMA chunk */
142 static unsigned long SLMEndAddr; /* expected end addr */
143 static unsigned long SLMSliceSize; /* size of one DMA chunk */
148 static DECLARE_WAIT_QUEUE_HEAD(slm_wait); /* waiting for buffer */
149 static DECLARE_WAIT_QUEUE_HEAD(print_wait); /* waiting for printing finished */
152 #define SLMSTAT_OK 0x00
153 #define SLMSTAT_ORNERY 0x02
154 #define SLMSTAT_TONER 0x03
155 #define SLMSTAT_WARMUP 0x04
156 #define SLMSTAT_PAPER 0x05
157 #define SLMSTAT_DRUM 0x06
158 #define SLMSTAT_INJAM 0x07
159 #define SLMSTAT_THRJAM 0x08
160 #define SLMSTAT_OUTJAM 0x09
161 #define SLMSTAT_COVER 0x0a
162 #define SLMSTAT_FUSER 0x0b
163 #define SLMSTAT_IMAGER 0x0c
164 #define SLMSTAT_MOTOR 0x0d
165 #define SLMSTAT_VIDEO 0x0e
166 #define SLMSTAT_SYSTO 0x10
167 #define SLMSTAT_OPCODE 0x12
168 #define SLMSTAT_DEVNUM 0x15
169 #define SLMSTAT_PARAM 0x1a
170 #define SLMSTAT_ACSITO 0x1b /* driver defined */
171 #define SLMSTAT_NOTALL 0x1c /* driver defined */
173 static char *SLMErrors[] = {
174 /* 0x00 */ "OK and ready",
176 /* 0x02 */ "ornery printer",
177 /* 0x03 */ "toner empty",
178 /* 0x04 */ "warming up",
179 /* 0x05 */ "paper empty",
180 /* 0x06 */ "drum empty",
181 /* 0x07 */ "input jam",
182 /* 0x08 */ "through jam",
183 /* 0x09 */ "output jam",
184 /* 0x0a */ "cover open",
185 /* 0x0b */ "fuser malfunction",
186 /* 0x0c */ "imager malfunction",
187 /* 0x0d */ "motor malfunction",
188 /* 0x0e */ "video malfunction",
190 /* 0x10 */ "printer system timeout",
192 /* 0x12 */ "invalid operation code",
195 /* 0x15 */ "invalid device number",
200 /* 0x1a */ "invalid parameter list",
201 /* 0x1b */ "ACSI timeout",
202 /* 0x1c */ "not all printed"
205 #define N_ERRORS (sizeof(SLMErrors)/sizeof(*SLMErrors))
207 /* real (driver caused) error? */
208 #define IS_REAL_ERROR(x) (x > 0x10)
215 { "Letter", 2400, 3180 },
216 { "Legal", 2400, 4080 },
217 { "A4", 2336, 3386 },
221 #define N_STD_SIZES (sizeof(StdPageSize)/sizeof(*StdPageSize))
223 #define SLM_BUFFER_SIZE (2336*3386/8) /* A4 for now */
224 #define SLM_DMA_AMOUNT 255 /* #sectors to program the DMA for */
226 #ifdef SLM_CONTINUOUS_DMA
227 # define SLM_DMA_INT_OFFSET 0 /* DMA goes until seccnt 0, no offs */
228 # define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */
229 # define SLM_SLICE_SIZE(w) (255*512)
231 # define SLM_DMA_INT_OFFSET 32 /* 32 Byte ST-DMA FIFO */
232 # define SLM_DMA_END_OFFSET 32 /* 32 Byte ST-DMA FIFO */
233 # define SLM_SLICE_SIZE(w) ((254*512)/(w/8)*(w/8))
236 /* calculate the number of jiffies to wait for 'n' bytes */
237 #ifdef SLM_CONT_CNT_REPROG
238 #define DMA_TIME_FOR(n) 50
239 #define DMA_STARTUP_TIME 0
241 #define DMA_TIME_FOR(n) (n/1400-1)
242 #define DMA_STARTUP_TIME 650
245 /***************************** Prototypes *****************************/
247 static char *slm_errstr( int stat );
248 static int slm_getstats( char *buffer, int device );
249 static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t
251 static void start_print( int device );
252 static void slm_interrupt(int irc, void *data, struct pt_regs *fp);
253 static void slm_test_ready( unsigned long dummy );
254 static void set_dma_addr( unsigned long paddr );
255 static unsigned long get_dma_addr( void );
256 static ssize_t slm_write( struct file *file, const char *buf, size_t count,
258 static int slm_ioctl( struct inode *inode, struct file *file, unsigned int
259 cmd, unsigned long arg );
260 static int slm_open( struct inode *inode, struct file *file );
261 static int slm_release( struct inode *inode, struct file *file );
262 static int slm_req_sense( int device );
263 static int slm_mode_sense( int device, char *buffer, int abs_flag );
265 static int slm_mode_select( int device, char *buffer, int len, int
268 static int slm_get_pagesize( int device, int *w, int *h );
270 /************************* End of Prototypes **************************/
273 static struct timer_list slm_timer = { function: slm_test_ready };
275 static struct file_operations slm_fops = {
281 release: slm_release,
285 /* ---------------------------------------------------------------------- */
286 /* Status Functions */
289 static char *slm_errstr( int stat )
295 if (stat >= 0 && stat < N_ERRORS && (p = SLMErrors[stat]))
297 sprintf( str, "unknown status 0x%02x", stat );
302 static int slm_getstats( char *buffer, int device )
304 { int len = 0, stat, i, w, h;
305 unsigned char buf[256];
307 stat = slm_mode_sense( device, buf, 0 );
308 if (IS_REAL_ERROR(stat))
311 #define SHORTDATA(i) ((buf[i] << 8) | buf[i+1])
312 #define BOOLDATA(i,mask) ((buf[i] & mask) ? "on" : "off")
317 len += sprintf( buffer+len, "Status\t\t%s\n",
318 slm_errstr( stat ) );
319 len += sprintf( buffer+len, "Page Size\t%dx%d",
322 for( i = 0; i < N_STD_SIZES; ++i ) {
323 if (w == StdPageSize[i].w && h == StdPageSize[i].h)
327 len += sprintf( buffer+len, " (%s)", StdPageSize[i].name );
328 buffer[len++] = '\n';
330 len += sprintf( buffer+len, "Top/Left Margin\t%d/%d\n",
331 SHORTDATA( 5 ), SHORTDATA( 7 ) );
332 len += sprintf( buffer+len, "Manual Feed\t%s\n",
333 BOOLDATA( 9, 0x01 ) );
334 len += sprintf( buffer+len, "Input Select\t%d\n",
336 len += sprintf( buffer+len, "Auto Select\t%s\n",
337 BOOLDATA( 9, 0x10 ) );
338 len += sprintf( buffer+len, "Prefeed Paper\t%s\n",
339 BOOLDATA( 9, 0x20 ) );
340 len += sprintf( buffer+len, "Thick Pixels\t%s\n",
341 BOOLDATA( 9, 0x40 ) );
342 len += sprintf( buffer+len, "H/V Resol.\t%d/%d dpi\n",
343 SHORTDATA( 12 ), SHORTDATA( 10 ) );
344 len += sprintf( buffer+len, "System Timeout\t%d\n",
346 len += sprintf( buffer+len, "Scan Time\t%d\n",
348 len += sprintf( buffer+len, "Page Count\t%d\n",
350 len += sprintf( buffer+len, "In/Out Cap.\t%d/%d\n",
351 SHORTDATA( 19 ), SHORTDATA( 21 ) );
352 len += sprintf( buffer+len, "Stagger Output\t%s\n",
353 BOOLDATA( 23, 0x01 ) );
354 len += sprintf( buffer+len, "Output Select\t%d\n",
355 (buf[23] >> 1) & 7 );
356 len += sprintf( buffer+len, "Duplex Print\t%s\n",
357 BOOLDATA( 23, 0x10 ) );
358 len += sprintf( buffer+len, "Color Sep.\t%s\n",
359 BOOLDATA( 23, 0x20 ) );
365 static ssize_t slm_read( struct file *file, char *buf, size_t count,
369 struct inode *node = file->f_dentry->d_inode;
376 if (!(page = __get_free_page( GFP_KERNEL )))
379 length = slm_getstats( (char *)page, MINOR(node->i_rdev) );
384 if (file->f_pos >= length) {
388 if (count + file->f_pos > length)
389 count = length - file->f_pos;
390 end = count + file->f_pos;
391 if (copy_to_user(buf, (char *)page + file->f_pos, count)) {
396 out: free_page( page );
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 if (copy_from_user(BufferP, buf, n))
659 if (filled == BufferSize) {
660 /* Check the paper size again! The user may have switched it in the
661 * time between starting the data and finishing them. Would end up in
662 * a trashy page... */
663 if (slm_get_pagesize( device, &w, &h ))
665 if (BufferSize != w*h/8) {
666 printk( KERN_NOTICE "slm%d: page size changed while printing\n",
672 /* choose a slice size that is a multiple of the line size */
673 #ifndef SLM_CONT_CNT_REPROG
674 SLMSliceSize = SLM_SLICE_SIZE(w);
677 start_print( device );
678 sleep_on( &print_wait );
679 if (SLMError && IS_REAL_ERROR(SLMError)) {
680 printk( KERN_ERR "slm%d: %s\n", device, slm_errstr(SLMError) );
686 wake_up_interruptible( &slm_wait );
693 /* ---------------------------------------------------------------------- */
694 /* ioctl Functions */
697 static int slm_ioctl( struct inode *inode, struct file *file,
698 unsigned int cmd, unsigned long arg )
700 { int device = MINOR( inode->i_rdev ), err;
702 /* I can think of setting:
707 * but haven't implemented that yet :-)
708 * BTW, has anybody better docs about the MODE SENSE/MODE SELECT data?
712 case SLMIORESET: /* reset buffer, i.e. empty the buffer */
713 if (!(file->f_mode & 2))
715 if (SLMState == PRINTING)
719 wake_up_interruptible( &slm_wait );
722 case SLMIOGSTAT: { /* get status */
726 stat = slm_req_sense( device );
728 str = slm_errstr( stat );
730 (long *)&((struct SLM_status *)arg)->stat))
732 if (copy_to_user( ((struct SLM_status *)arg)->str, str,
739 case SLMIOGPSIZE: { /* get paper size */
742 if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
744 if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
746 if (put_user(h, (long *)&((struct SLM_paper_size *)arg)->height))
751 case SLMIOGMFEED: /* get manual feed */
754 case SLMIOSPSIZE: /* set paper size */
757 case SLMIOSMFEED: /* set manual feed */
765 /* ---------------------------------------------------------------------- */
766 /* Opening and Closing */
769 static int slm_open( struct inode *inode, struct file *file )
774 device = MINOR(inode->i_rdev);
775 if (device >= N_SLM_Printers)
777 sip = &slm_info[device];
779 if (file->f_mode & 2) {
780 /* open for writing is exclusive */
785 if (file->f_mode & 1) {
786 /* open for writing is exclusive */
796 static int slm_release( struct inode *inode, struct file *file )
801 device = MINOR(inode->i_rdev);
802 sip = &slm_info[device];
805 if (file->f_mode & 2)
807 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;
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 );
996 static devfs_handle_t devfs_handle;
1001 if (devfs_register_chrdev( MAJOR_NR, "slm", &slm_fops )) {
1002 printk( KERN_ERR "Unable to get major %d for ACSI SLM\n", MAJOR_NR );
1006 if (!(SLMBuffer = atari_stram_alloc( SLM_BUFFER_SIZE, "SLM" ))) {
1007 printk( KERN_ERR "Unable to get SLM ST-Ram buffer.\n" );
1008 devfs_unregister_chrdev( MAJOR_NR, "slm" );
1011 BufferP = SLMBuffer;
1014 devfs_handle = devfs_mk_dir (NULL, "slm", NULL);
1015 devfs_register_series (devfs_handle, "%u", MAX_SLM, DEVFS_FL_DEFAULT,
1016 MAJOR_NR, 0, S_IFCHR | S_IRUSR | S_IWUSR,
1024 void acsi_attach_SLMs( int (*attach_func)( int, int ) );
1026 int init_module(void)
1030 if ((err = slm_init()))
1032 /* This calls attach_slm() for every target/lun where acsi.c detected a
1034 acsi_attach_SLMs( attach_slm );
1038 void cleanup_module(void)
1040 devfs_unregister (devfs_handle);
1041 if (devfs_unregister_chrdev( MAJOR_NR, "slm" ) != 0)
1042 printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
1043 atari_stram_free( SLMBuffer );