/* Version 1.0.0 is the backpack driver for which source is not available Version 2.0.0 is the first to have source released */ /* messages parameter */ int verbose=0; #define BACKPACK_VERSION "2.0.0" #define EXPORT_SYMTAB #include #include #include #include #include #ifdef CONFIG_PARPORT_MODULE #define CONFIG_PARPORT #endif #ifdef CONFIG_PARPORT #include #endif #include "ppc6lnx.c" #include "paride.h" #define PPCSTRUCT(pi) ((PPC *)(pi->private)) /****************************************************************/ /* ATAPI CDROM DRIVE REGISTERS */ #define ATAPI_DATA 0 /* data port */ #define ATAPI_ERROR 1 /* error register (read) */ #define ATAPI_FEATURES 1 /* feature register (write) */ #define ATAPI_INT_REASON 2 /* interrupt reason register */ #define ATAPI_COUNT_LOW 4 /* byte count register (low) */ #define ATAPI_COUNT_HIGH 5 /* byte count register (high) */ #define ATAPI_DRIVE_SEL 6 /* drive select register */ #define ATAPI_STATUS 7 /* status port (read) */ #define ATAPI_COMMAND 7 /* command port (write) */ #define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */ #define ATAPI_DEVICE_CONTROL 0x0e /* device control (write) */ /****************************************************************/ static int backpack_read_regr(PIA *pi, int cont, int reg) { unsigned int out; /* check for bad settings */ if (reg<0 || reg>7 || cont<0 || cont>2) { return(-1); } out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg); return(out); } static void backpack_write_regr(PIA *pi, int cont, int reg, int val) { /* check for bad settings */ if (reg>=0 && reg<=7 && cont>=0 && cont<=1) { ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(BYTE)val); } } static void backpack_write_block( PIA *pi, char * buf, int len ) { ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(DWORD)len>>1); } static void backpack_read_block( PIA *pi, char * buf, int len ) { ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(DWORD)len>>1); } static void backpack_connect ( PIA *pi ) { if(verbose) { printk(KERN_DEBUG "connect\n"); } if(pi->mode >=2) { PPCSTRUCT(pi)->mode=4+pi->mode-2; } else if(pi->mode==1) { PPCSTRUCT(pi)->mode=3; } else { PPCSTRUCT(pi)->mode=1; } ppc6_open(PPCSTRUCT(pi)); ppc6_wr_extout(PPCSTRUCT(pi),0x3); } static void backpack_disconnect ( PIA *pi ) { if(verbose) { printk("disconnect\n"); } ppc6_wr_extout(PPCSTRUCT(pi),0x0); ppc6_close(PPCSTRUCT(pi)); } static int backpack_test_port ( PIA *pi ) /* check for 8-bit port */ { unsigned int index=0; if(verbose) { printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%x\n", ((struct pardevice*)(pi->pardev))->port->modes, ((struct pardevice *)(pi->pardev))->port->base); } /*copy over duplicate stuff.. initialize state info*/ PPCSTRUCT(pi)->ppc_id=pi->unit; PPCSTRUCT(pi)->lpt_addr=pi->port; #ifdef CONFIG_PARPORT_PC_MODULE #define CONFIG_PARPORT_PC #endif #ifdef CONFIG_PARPORT_PC /* look at the parport device to see if what modes we can use */ if(((struct pardevice *)(pi->pardev))->port->modes & (PARPORT_MODE_EPP) ) { return 5; /* Can do EPP*/ } else if(((struct pardevice *)(pi->pardev))->port->modes & (PARPORT_MODE_TRISTATE) ) { return 2; } else /*Just flat SPP*/ { return 1; } #else /* there is no way of knowing what kind of port we have default to the highest mode possible */ return 5; #endif } static int backpack_probe_unit ( PIA *pi ) { DWORD temp; WORD old_ecr; BYTE out; if(verbose) { printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port); } /*SET PPC UNIT NUMBER*/ PPCSTRUCT(pi)->ppc_id=pi->unit; /*LOWER DOWN TO UNIDIRECTIONAL*/ PPCSTRUCT(pi)->mode=1; out=ppc6_open(PPCSTRUCT(pi)); if(verbose) { printk(KERN_DEBUG "ppc_open returned %2x\n",out); } if(out) { ppc6_close(PPCSTRUCT(pi)); return(1); if(verbose) { printk("<1> leaving probe\n"); } } else { if(verbose) { printk("<1> Failed open\n"); } return(0); } } static void backpack_log_adapter( PIA *pi, char * scratch, int verbose ) { char *mode_string[5]= {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"}; printk("%s: BACKPACK Protocol Driver V2.0.0\n",pi->device); printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device); printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n", pi->device,BACKPACK_VERSION,pi->port); printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device, pi->unit,pi->mode,mode_string[pi->mode],pi->delay); } static void backpack_init_proto(PIA *pi) { int i; /* allocate a state structure for this item */ pi->private=(int)kmalloc(sizeof(PPC),GFP_KERNEL); for(i=0;iprivate))[i]=0; } if(!pi->private) { printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n",pi->device); return; } else { MOD_INC_USE_COUNT; } } static void backpack_release_proto(PIA *pi) { MOD_DEC_USE_COUNT; /* free after use count decrimented so that we aren't using it when it is decrimented */ kfree((void *)(pi->private)); } struct pi_protocol backpack = { "backpack", /* name for proto*/ 0, /* index into proto table */ 5, /* max mode =5 */ 2, /* 2-5 use epp (need 8 ports) */ 0, /* no delay (not used anyway) */ 255, /* we can have units up to 255 */ backpack_write_regr, backpack_read_regr, backpack_write_block, backpack_read_block, backpack_connect, backpack_disconnect, backpack_test_port, backpack_probe_unit, 0, backpack_log_adapter, backpack_init_proto, backpack_release_proto }; EXPORT_SYMBOL(backpack_write_regr); EXPORT_SYMBOL(backpack_read_regr); EXPORT_SYMBOL(backpack_write_block); EXPORT_SYMBOL(backpack_read_block); EXPORT_SYMBOL(backpack_connect); EXPORT_SYMBOL(backpack_disconnect); EXPORT_SYMBOL(backpack_test_port); EXPORT_SYMBOL(backpack_probe_unit); EXPORT_SYMBOL(backpack_log_adapter); EXPORT_SYMBOL(backpack_init_proto); EXPORT_SYMBOL(backpack_release_proto); /*---------------------------MODULE STUFF-----------------------*/ #ifdef MODULE /*module information*/ int init_module(void) { printk("BACKPACK Protocol Driver V2.0.0\n"); printk("Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n"); if(verbose) { printk(KERN_DEBUG "VERBOSE ON!\n"); } return pi_register(&backpack) - 1; } void cleanup_module(void) { pi_unregister(&backpack); } MODULE_AUTHOR("Micro Solutions Inc."); MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE"); MODULE_PARM(verbose,"i"); #endif