/*
** -----------------------------------------------------------------------------
**
** Perle Specialix driver for Linux
** Ported from existing RIO Driver for SCO sources.
*
* (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
** Module : rioboot.c
** SID : 1.3
** Last Modified : 11/6/98 10:33:36
** Retrieved : 11/6/98 10:33:48
**
** ident @(#)rioboot.c 1.3
**
** -----------------------------------------------------------------------------
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/termios.h>
#include <linux/serial.h>
#include <linux/vmalloc.h>
#include <linux/generic_serial.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include "linux_compat.h"
#include "rio_linux.h"
#include "pkt.h"
#include "daemon.h"
#include "rio.h"
#include "riospace.h"
#include "cmdpkt.h"
#include "map.h"
#include "rup.h"
#include "port.h"
#include "riodrvr.h"
#include "rioinfo.h"
#include "func.h"
#include "errors.h"
#include "pci.h"
#include "parmmap.h"
#include "unixrup.h"
#include "board.h"
#include "host.h"
#include "phb.h"
#include "link.h"
#include "cmdblk.h"
#include "route.h"
static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP);
static const unsigned char RIOAtVec2Ctrl[] = {
/* 0 */ INTERRUPT_DISABLE,
/* 1 */ INTERRUPT_DISABLE,
/* 2 */ INTERRUPT_DISABLE,
/* 3 */ INTERRUPT_DISABLE,
/* 4 */ INTERRUPT_DISABLE,
/* 5 */ INTERRUPT_DISABLE,
/* 6 */ INTERRUPT_DISABLE,
/* 7 */ INTERRUPT_DISABLE,
/* 8 */ INTERRUPT_DISABLE,
/* 9 */ IRQ_9 | INTERRUPT_ENABLE,
/* 10 */ INTERRUPT_DISABLE,
/* 11 */ IRQ_11 | INTERRUPT_ENABLE,
/* 12 */ IRQ_12 | INTERRUPT_ENABLE,
/* 13 */ INTERRUPT_DISABLE,
/* 14 */ INTERRUPT_DISABLE,
/* 15 */ IRQ_15 | INTERRUPT_ENABLE
};
/**
* RIOBootCodeRTA - Load RTA boot code
* @p: RIO to load
* @rbp: Download descriptor
*
* Called when the user process initiates booting of the card firmware.
* Lads the firmware
*/
int RIOBootCodeRTA(struct rio_info *p, struct DownLoad * rbp)
{
int offset;
func_enter();
rio_dprintk(RIO_DEBUG_BOOT, "Data at user address %p\n", rbp->DataP);
/*
** Check that we have set asside enough memory for this
*/
if (rbp->Count > SIXTY_FOUR_K) {
rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n");
p->RIOError.Error = HOST_FILE_TOO_LARGE;
func_exit();
return -ENOMEM;
}
if (p->RIOBooting) {
rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n");
p->RIOError.Error = BOOT_IN_PROGRESS;
func_exit();
return -EBUSY;
}
/*
** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary,
** so calculate how far we have to move the data up the buffer
** to achieve this.
*/
offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) % RTA_BOOT_DATA_SIZE;
/*
** Be clean, and clear the 'unused' portion of the boot buffer,
** because it will (eventually) be part of the Rta run time environment
** and so should be zeroed.
*/
memset(p->RIOBootPackets, 0, offset);
/*
** Copy the data from user space into the array
*/
if (copy_from_user(((u8 *)p->RIOBootPackets) + offset, rbp->DataP, rbp->Count)) {
rio_dprintk(RIO_DEBUG_BOOT, "Bad data copy from user space\n");
p->RIOError.Error = COPYIN_FAILED;
func_exit();
return -EFAULT;
}
/*
** Make sure that our copy of the size includes that offset we discussed
** earlier.
*/
p->RIONumBootPkts = (rbp->Count + offset) / RTA_BOOT_DATA_SIZE;
p->RIOBootCount = rbp->Count;
func_exit();
return 0;
}
/**
* rio_start_card_running - host card start<