linux/drivers/block/paride/bpck6.c
<<
>>
Prefs
   1/*
   2        backpack.c (c) 2001 Micro Solutions Inc.
   3                Released under the terms of the GNU General Public license
   4
   5        backpack.c is a low-level protocol driver for the Micro Solutions
   6                "BACKPACK" parallel port IDE adapter
   7                (Works on Series 6 drives)
   8
   9        Written by: Ken Hahn     (linux-dev@micro-solutions.com)
  10                    Clive Turvey (linux-dev@micro-solutions.com)
  11
  12*/
  13
  14/*
  15   This is Ken's linux wrapper for the PPC library
  16   Version 1.0.0 is the backpack driver for which source is not available
  17   Version 2.0.0 is the first to have source released 
  18   Version 2.0.1 is the "Cox-ified" source code 
  19   Version 2.0.2 - fixed version string usage, and made ppc functions static 
  20*/
  21
  22
  23/* PARAMETERS */
  24static int verbose; /* set this to 1 to see debugging messages and whatnot */
  25
  26#define BACKPACK_VERSION "2.0.2"
  27
  28#include <linux/module.h>
  29#include <linux/init.h>
  30#include <linux/kernel.h>
  31#include <linux/slab.h>
  32#include <linux/types.h>
  33#include <asm/io.h>
  34#include <linux/parport.h>
  35
  36#include "ppc6lnx.c"
  37#include "paride.h"
  38
  39 
  40
  41#define PPCSTRUCT(pi) ((Interface *)(pi->private))
  42
  43/****************************************************************/
  44/*
  45 ATAPI CDROM DRIVE REGISTERS
  46*/
  47#define ATAPI_DATA       0      /* data port                  */
  48#define ATAPI_ERROR      1      /* error register (read)      */
  49#define ATAPI_FEATURES   1      /* feature register (write)   */
  50#define ATAPI_INT_REASON 2      /* interrupt reason register  */
  51#define ATAPI_COUNT_LOW  4      /* byte count register (low)  */
  52#define ATAPI_COUNT_HIGH 5      /* byte count register (high) */
  53#define ATAPI_DRIVE_SEL  6      /* drive select register      */
  54#define ATAPI_STATUS     7      /* status port (read)         */
  55#define ATAPI_COMMAND    7      /* command port (write)       */
  56#define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */
  57#define ATAPI_DEVICE_CONTROL 0x0e /* device control (write)   */
  58/****************************************************************/
  59
  60static int bpck6_read_regr(PIA *pi, int cont, int reg)
  61{
  62        unsigned int out;
  63
  64        /* check for bad settings */
  65        if (reg<0 || reg>7 || cont<0 || cont>2)
  66        {
  67                return(-1);
  68        }
  69        out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg);
  70        return(out);
  71}
  72
  73static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
  74{
  75        /* check for bad settings */
  76        if (reg>=0 && reg<=7 && cont>=0 && cont<=1)
  77        {
  78                ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(u8)val);
  79        }
  80}
  81
  82static void bpck6_write_block( PIA *pi, char * buf, int len )
  83{
  84        ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1); 
  85}
  86
  87static void bpck6_read_block( PIA *pi, char * buf, int len )
  88{
  89        ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
  90}
  91
  92static void bpck6_connect ( PIA *pi  )
  93{
  94        if(verbose)
  95        {
  96                printk(KERN_DEBUG "connect\n");
  97        }
  98
  99        if(pi->mode >=2)
 100        {
 101                PPCSTRUCT(pi)->mode=4+pi->mode-2;       
 102        }
 103        else if(pi->mode==1)
 104        {
 105                PPCSTRUCT(pi)->mode=3;  
 106        }
 107        else
 108        {
 109                PPCSTRUCT(pi)->mode=1;          
 110        }
 111
 112        ppc6_open(PPCSTRUCT(pi));  
 113        ppc6_wr_extout(PPCSTRUCT(pi),0x3);
 114}
 115
 116static void bpck6_disconnect ( PIA *pi )
 117{
 118        if(verbose)
 119        {
 120                printk("disconnect\n");
 121        }
 122        ppc6_wr_extout(PPCSTRUCT(pi),0x0);
 123        ppc6_close(PPCSTRUCT(pi));
 124}
 125
 126static int bpck6_test_port ( PIA *pi )   /* check for 8-bit port */
 127{
 128        if(verbose)
 129        {
 130                printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%lx\n",
 131                        ((struct pardevice*)(pi->pardev))->port->modes,
 132                        ((struct pardevice *)(pi->pardev))->port->base); 
 133        }
 134
 135        /*copy over duplicate stuff.. initialize state info*/
 136        PPCSTRUCT(pi)->ppc_id=pi->unit;
 137        PPCSTRUCT(pi)->lpt_addr=pi->port;
 138
 139        /* look at the parport device to see if what modes we can use */
 140        if(((struct pardevice *)(pi->pardev))->port->modes & 
 141                (PARPORT_MODE_EPP)
 142          )
 143        {
 144                return 5; /* Can do EPP*/
 145        }
 146        else if(((struct pardevice *)(pi->pardev))->port->modes & 
 147                        (PARPORT_MODE_TRISTATE)
 148               )
 149        {
 150                return 2;
 151        }
 152        else /*Just flat SPP*/
 153        {
 154                return 1;
 155        }
 156}
 157
 158static int bpck6_probe_unit ( PIA *pi )
 159{
 160        int out;
 161
 162        if(verbose)
 163        {
 164                printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port);
 165        }
 166
 167        /*SET PPC UNIT NUMBER*/
 168        PPCSTRUCT(pi)->ppc_id=pi->unit;
 169
 170        /*LOWER DOWN TO UNIDIRECTIONAL*/
 171        PPCSTRUCT(pi)->mode=1;          
 172
 173        out=ppc6_open(PPCSTRUCT(pi));
 174
 175        if(verbose)
 176        {
 177                printk(KERN_DEBUG "ppc_open returned %2x\n",out);
 178        }
 179
 180        if(out)
 181        {
 182                ppc6_close(PPCSTRUCT(pi));
 183                if(verbose)
 184                {
 185                        printk(KERN_DEBUG "leaving probe\n");
 186                }
 187               return(1);
 188        }
 189        else
 190        {
 191                if(verbose)
 192                {
 193                        printk(KERN_DEBUG "Failed open\n");
 194                }
 195                return(0);
 196        }
 197}
 198
 199static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
 200{
 201        char *mode_string[5]=
 202                {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
 203
 204        printk("%s: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n",pi->device);
 205        printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device);
 206        printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n",
 207                pi->device,BACKPACK_VERSION,pi->port);
 208        printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device,
 209                pi->unit,pi->mode,mode_string[pi->mode],pi->delay);
 210}
 211
 212static int bpck6_init_proto(PIA *pi)
 213{
 214        Interface *p = kzalloc(sizeof(Interface), GFP_KERNEL);
 215
 216        if (p) {
 217                pi->private = (unsigned long)p;
 218                return 0;
 219        }
 220
 221        printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n", pi->device); 
 222        return -1;
 223}
 224
 225static void bpck6_release_proto(PIA *pi)
 226{
 227        kfree((void *)(pi->private)); 
 228}
 229
 230static struct pi_protocol bpck6 = {
 231        .owner          = THIS_MODULE,
 232        .name           = "bpck6",
 233        .max_mode       = 5,
 234        .epp_first      = 2, /* 2-5 use epp (need 8 ports) */
 235        .max_units      = 255,
 236        .write_regr     = bpck6_write_regr,
 237        .read_regr      = bpck6_read_regr,
 238        .write_block    = bpck6_write_block,
 239        .read_block     = bpck6_read_block,
 240        .connect        = bpck6_connect,
 241        .disconnect     = bpck6_disconnect,
 242        .test_port      = bpck6_test_port,
 243        .probe_unit     = bpck6_probe_unit,
 244        .log_adapter    = bpck6_log_adapter,
 245        .init_proto     = bpck6_init_proto,
 246        .release_proto  = bpck6_release_proto,
 247};
 248
 249static int __init bpck6_init(void)
 250{
 251        printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
 252        printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
 253        if(verbose)
 254                printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
 255        return paride_register(&bpck6);
 256}
 257
 258static void __exit bpck6_exit(void)
 259{
 260        paride_unregister(&bpck6);
 261}
 262
 263MODULE_LICENSE("GPL");
 264MODULE_AUTHOR("Micro Solutions Inc.");
 265MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
 266module_param(verbose, bool, 0644);
 267module_init(bpck6_init)
 268module_exit(bpck6_exit)
 269