Cleaned up isolation protocol.

This commit is contained in:
Michael Brown
2005-04-15 12:25:17 +00:00
parent 344ea224b4
commit 1980018b8b
2 changed files with 437 additions and 240 deletions

View File

@@ -18,69 +18,65 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Portions of this code:
* Copyright (C) 2001 P.J.H.Fox (fox@roestock.demon.co.uk)
* Copyright (C) 2001 P.J.H.Fox (fox@roestock.demon.co.uk)
*
*
*
* REVISION HISTORY:
* ================
* Version 0.1 April 26, 2002 TJL
* Version 0.2 01/08/2003 TJL Renamed from 3c515_isapnp.h
* Version 0.2 01/08/2003 TJL Renamed from 3c515_isapnp.h
*
*
* Generalised into an ISAPnP bus that can be used by more than just
* the 3c515 by Michael Brown <mbrown@fensystems.co.uk>
*
***************************************************************************/
/*extern int read_port;*/
/*#define DEBUG*/
#define ADDRESS_ADDR 0x0279
#define WRITEDATA_ADDR 0x0a79
/* MIN and MAX READ_ADDR must have the bottom two bits set */
#define MIN_READ_ADDR 0x0203
#define START_READ_ADDR 0x203
#define MAX_READ_ADDR 0x03ff
/* READ_ADDR_STEP must be a multiple of 4 */
#ifndef READ_ADDR_STEP
#define READ_ADDR_STEP 8
#endif
#ifndef ISAPNP_H
#define ISAPNP_H
#ifdef EDEBUG
static int x;
#define ADDRESS(x) (outb(x, ADDRESS_ADDR), printf("\nAddress: %hX", x))
#define WRITE_DATA(x) (outb(x, WRITEDATA_ADDR), printf(" WR(%hX)", x & 0xff))
#define READ_DATA (x = inb(read_port), printf(" RD(%hX)", x & 0xff), x)
#define READ_IOPORT(p) (x = inb(p), printf(" [%hX](%hX)", p, x & 0xff), x)
#else /* !DEBUG */
#define ADDRESS(x) outb(x, ADDRESS_ADDR)
#define WRITE_DATA(x) outb(x, WRITEDATA_ADDR)
#define READ_DATA inb(read_port)
#define READ_IOPORT(p) inb(p)
#endif /* !DEBUG */
#include "isa_ids.h"
#include "dev.h"
/*
* ISAPnP constants
*
*/
#define INIT_LENGTH 32
#define INITDATA { 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe,\
0xdf, 0x6f, 0x37, 0x1b, 0x0d, 0x86, 0xc3, 0x61,\
0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1,\
0xe8, 0x74, 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 }
/* Port addresses */
#define ISAPNP_ADDRESS 0x279
#define ISAPNP_WRITE_DATA 0xa79
#define ISAPNP_READ_PORT_MIN 0x213 /* ISAPnP spec says 0x203, but
* Linux ISAPnP starts at
* 0x213 with no explanatory
* comment. 0x203 probably
* clashes with something. */
#define ISAPNP_READ_PORT_MAX 0x3ff
#define ISAPNP_READ_PORT_STEP 0x08 /* Can be any multiple of 4 */
/* Registers */
#define SetRdPort(x) (ADDRESS(0x00),WRITE_DATA((x)>>2),read_port=((x)|3))
#define SERIALISOLATION ADDRESS(0x01)
#define CONFIGCONTROL ADDRESS(0x02)
#define Wake(x) (ADDRESS(0x03),WRITE_DATA(x))
#define RESOURCEDATA (ADDRESS(0x04),READ_DATA)
#define STATUS (ADDRESS(0x05),READ_DATA)
#define CARDSELECTNUMBER ADDRESS(0x06)
#define LOGICALDEVICENUMBER ADDRESS(0x07)
#define ACTIVATE ADDRESS(0x30)
#define IORANGECHECK ADDRESS(0x31)
#define ISAPNP_READPORT 0x00
#define ISAPNP_SERIALISOLATION 0x01
#define ISAPNP_CONFIGCONTROL 0x02
#define ISAPNP_WAKE 0x03
#define ISAPNP_RESOURCEDATA 0x04
#define ISAPNP_STATUS 0x05
#define ISAPNP_CARDSELECTNUMBER 0x06
#define ISAPNP_LOGICALDEVICENUMBER 0x07
#define ISAPNP_ACTIVATE 0x30
#define ISAPNP_IORANGECHECK 0x31
/* Bits */
#define CONFIG_RESET 0x01
#define CONFIG_WAIT_FOR_KEY 0x02
#define CONFIG_RESET_CSN 0x04
#define CONFIG_RESET_DRV 0x07
/* Bits in the CONFIGCONTROL register */
#define ISAPNP_CONFIG_RESET ( 1 << 0 )
#define ISAPNP_CONFIG_WAIT_FOR_KEY ( 1 << 1 )
#define ISAPNP_CONFIG_RESET_CSN ( 1 << 2 )
#define ISAPNP_CONFIG_RESET_DRV ( ISAPNP_CONFIG_RESET | \
ISAPNP_CONFIG_WAIT_FOR_KEY | \
ISAPNP_CONFIG_RESET_CSN )
/* The LFSR used for the initiation key and for checksumming */
#define ISAPNP_LFSR_SEED 0x6a
/* Short Tags */
#define PnPVerNo_TAG 0x01
@@ -122,3 +118,70 @@ static int x;
#define RsvdLongE_TAG 0xFE
#define RsvdLongF_TAG 0xFF
#define NewBoard_PSEUDOTAG 0x100
/*
* An ISAPnP serial identifier
*
*/
union isapnp_identifier {
char bytes[9];
struct {
uint16_t vendor_id;
uint16_t product_id;
uint32_t serial;
uint8_t checksum;
} __attribute__ (( packed ));
} __attribute__ (( packed ));
/*
* A physical ISAPnP device
*
*/
struct isapnp_device {
char *magic; /* must be first */
const char *name;
unsigned char csn;
uint16_t vendor_id;
uint16_t prod_id;
int already_tried;
};
/*
* An individual ISAPnP device identified by ID
*
*/
struct isapnp_id {
const char *name;
uint16_t vendor_id, prod_id;
};
/*
* An ISAPnP driver, with a device ID (struct isapnp_id) table.
*
*/
struct isapnp_driver {
const char *name;
struct isapnp_id *ids;
unsigned int id_count;
};
/*
* Define an ISAPnP driver
*
*/
#define ISAPNP_DRIVER( driver_name, isapnp_ids ) { \
.name = driver_name, \
.ids = isapnp_ids, \
.id_count = sizeof ( isapnp_ids ) / sizeof ( isapnp_ids[0] ), \
}
/*
* Functions in isapnp.c
*
*/
extern int find_isapnp_device ( struct isapnp_device *isapnp,
struct isapnp_driver *driver );
extern int find_isapnp_boot_device ( struct dev *dev,
struct isapnp_driver *driver );
#endif /* ISAPNP_H */