/* -*- mode: c; c-basic-offset: 8 -*- */
/* Copyright (C) 1999,2001
*
* Author: J.E.J.Bottomley@HansenPartnership.com
*
* This file contains all the logic for manipulating the CAT bus
* in a level 5 machine.
*
* The CAT bus is a serial configuration and test bus. Its primary
* uses are to probe the initial configuration of the system and to
* diagnose error conditions when a system interrupt occurs. The low
* level interface is fairly primitive, so most of this file consists
* of bit shift manipulations to send and receive packets on the
* serial bus */
#include <linux/types.h>
#include <linux/completion.h>
#include <linux/sched.h>
#include <asm/voyager.h>
#include <asm/vic.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/io.h>
#ifdef VOYAGER_CAT_DEBUG
#define CDEBUG(x) printk x
#else
#define CDEBUG(x)
#endif
/* the CAT command port */
#define CAT_CMD (sspb + 0xe)
/* the CAT data port */
#define CAT_DATA (sspb + 0xd)
/* the internal cat functions */
static void cat_pack(__u8 * msg, __u16 start_bit, __u8 * data, __u16 num_bits);
static void cat_unpack(__u8 * msg, __u16 start_bit, __u8 * data,
__u16 num_bits);
static void cat_build_header(__u8 * header, const __u16 len,
const __u16 smallest_reg_bits,
const __u16 longest_reg_bits);
static int cat_sendinst(voyager_module_t * modp, voyager_asic_t * asicp,
__u8 reg, __u8 op);
static int cat_getdata(voyager_module_t * modp, voyager_asic_t * asicp,
__u8 reg, __u8 * value);
static int cat_shiftout(__u8 * data, __u16 data_bytes, __u16 header_bytes,
__u8 pad_bits);
static int cat_write(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
__u8 value);
static int cat_read(voyager_module_t * modp, voyager_asic_t * asicp, __u8 reg,
__u8 * value);
static int cat_subread(voyager_module_t * modp, voyager_asic_t * asicp,
__u16 offset, __u16 len, void *buf);
static int cat_senddata(voyager_module_t * modp, voyager_asic_t * asicp,
__u8 reg, __u8 value);
static int cat_disconnect(voyager_module_t * modp, voyager_asic_t * asicp);
static int cat_connect(voyager_module_t * modp, voyager_asic_t * asicp);
static inline const char *cat_module_name(int module_id)
{
switch (module_id) {
case 0x10:
return "Processor Slot 0";
case 0x11:
return "Processor Slot 1";
case 0x12:
return "Processor Slot 2";
case 0x13:
return "Processor Slot 4";
case 0x14:
return "Memory Slot 0";
case 0x15:
return "Memory Slot 1";
case 0x18:
return "Primary Microchannel";
case 0x19:
return "Secondary Microchannel";
case 0x1a:
return "Power Supply Interface";
case 0x1c:
return "Processor Slot 5";
case 0x1d:
return "Processor Slot 6";
case 0x1e:
return "Processor Slot 7";
case 0x1f:
return "