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