Commit 57e34bbb authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] nsp_cs update from maintainer

parent 515a6f24
/*======================================================================
NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI hostadapter card driver
NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
Ver.2.8 Support 32bit MMIO mode
Support Synchronous Data TRansfer (SDTR) mode
Ver.2.0 Support 32bit PIO mode
Ver.1.1.2 Fix for scatter list buffer exceeds
Ver.1.1 Support scatter list
......@@ -23,7 +25,7 @@
***********************************************************************/
/* $Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $ */
/* $Id: nsp_cs.c,v 1.4 2002/10/15 15:57:01 elca Exp $ */
#ifdef NSP_KERNEL_2_2
#include <pcmcia/config.h>
......@@ -39,7 +41,6 @@
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/major.h>
......@@ -51,7 +52,6 @@
#include <../drivers/scsi/scsi.h>
#include <../drivers/scsi/hosts.h>
#include <../drivers/scsi/sd.h>
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
......@@ -60,20 +60,24 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
#include <pcmcia/bus_ops.h>
#include "nsp_cs.h"
MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.4 $");
MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i");
MODULE_PARM_DESC(pc_debug, "set debug level");
static char *version = "$Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $";
static char *version = "$Id: nsp_cs.c,v 1.4 2002/10/15 15:57:01 elca Exp $";
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
#else
#define DEBUG(n, args...) /* */
......@@ -108,48 +112,56 @@ static struct proc_dir_entry proc_scsi_nsp = {
static unsigned int irq_mask = 0xffff;
MODULE_PARM(irq_mask, "i");
MODULE_PARM_DESC(irq_mask, "IRQ mask bits");
MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xffff)");
static int irq_list[4] = { -1 };
MODULE_PARM(irq_list, "1-4i");
MODULE_PARM_DESC(irq_list, "IRQ number list");
MODULE_PARM_DESC(irq_list, "Use specified IRQ number. (default: auto select)");
/*----------------------------------------------------------------*/
/* driver state info, local to driver */
static char nspinfo[100]; /* description */
static int nsp_burst_mode = 2;
MODULE_PARM(nsp_burst_mode, "i");
MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
/* Release IO ports after configuration? */
static int free_ports = 0;
MODULE_PARM(free_ports, "i");
MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
/* /usr/src/linux/drivers/scsi/hosts.h */
static Scsi_Host_Template driver_template = {
/* next: NULL,*/
#if (KERNEL_VERSION(2,3,99) > LINUX_VERSION_CODE)
proc_dir: &proc_scsi_nsp, /* kernel 2.2 */
/* .next = NULL,*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
.proc_name = "nsp_cs", /* kernel 2.4 */
#else
proc_name: "nsp_cs", /* kernel 2.4 */
.proc_dir = &proc_scsi_nsp, /* kernel 2.2 */
#endif
/* proc_info: NULL,*/
name: "WorkBit NinjaSCSI-3/32Bi",
detect: nsp_detect,
release: nsp_release,
info: nsp_info,
/* command: NULL,*/
queuecommand: nsp_queuecommand,
/* eh_strategy_handler: nsp_eh_strategy,*/
eh_abort_handler: nsp_eh_abort,
eh_device_reset_handler: nsp_eh_device_reset,
eh_bus_reset_handler: nsp_eh_bus_reset,
eh_host_reset_handler: nsp_eh_host_reset,
abort: nsp_abort,
reset: nsp_reset,
/* slave_attach: NULL,*/
/* bios_param: NULL,*/
can_queue: 1,
this_id: SCSI_INITIATOR_ID,
sg_tablesize: SG_ALL,
cmd_per_lun: 1,
/* present: 0,*/
/* unchecked_isa_dma: 0,*/
use_clustering: DISABLE_CLUSTERING,
/* emulated: 0,*/
.proc_info = nsp_proc_info,
.name = "WorkBit NinjaSCSI-3/32Bi",
.detect = nsp_detect,
.release = nsp_release,
.info = nsp_info,
/* .command = NULL,*/
.queuecommand = nsp_queuecommand,
/* .eh_strategy_handler = nsp_eh_strategy,*/
/* .eh_abort_handler = nsp_eh_abort,*/
/* .eh_device_reset_handler = nsp_eh_device_reset,*/
.eh_bus_reset_handler = nsp_eh_bus_reset,
.eh_host_reset_handler = nsp_eh_host_reset,
.abort = nsp_abort,
.reset = nsp_reset,
/* .slave_attach = NULL,*/
/* .bios_param = NULL,*/
.can_queue = 1,
.this_id = NSP_INITIATOR_ID,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
/* .present = 0,*/
/* .unchecked_isa_dma = 0,*/
.use_clustering = DISABLE_CLUSTERING,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
.use_new_eh_code = 1,
#endif
/* .emulated = 0,*/
};
static dev_link_t *dev_list = NULL;
......@@ -162,18 +174,18 @@ static nsp_hw_data nsp_data;
static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
#ifdef PCMCIA_DEBUG
//unsigned int host_id = SCpnt->host->this_id;
//unsigned int base = SCpnt->host->io_port;
/*unsigned int host_id = SCpnt->host->this_id;*/
/*unsigned int base = SCpnt->host->io_port;*/
unsigned char target = SCpnt->target;
#endif
nsp_hw_data *data = &nsp_data;
DEBUG(0, __FUNCTION__ "() SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d\n",
SCpnt, target, SCpnt->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
DEBUG(0, "%s() SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d\n",
__FUNCTION__, SCpnt, target, SCpnt->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
//DEBUG(0, " before CurrentSC=0x%p\n", data->CurrentSC);
if(data->CurrentSC != NULL) {
printk(KERN_DEBUG " " __FUNCTION__ "() CurrentSC!=NULL this can't be happen\n");
printk(KERN_DEBUG " %s() CurrentSC!=NULL cannot happen!\n", __FUNCTION__);
data->CurrentSC = NULL;
SCpnt->result = DID_BAD_TARGET << 16;
done(SCpnt);
......@@ -184,13 +196,13 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt->scsi_done = done;
data->CurrentSC = SCpnt;
RESID = SCpnt->request_bufflen;
SCpnt->SCp.Status = -1;
SCpnt->SCp.Message = -1;
SCpnt->SCp.Status = CHECK_CONDITION;
SCpnt->SCp.Message = 0;
SCpnt->SCp.have_data_in = IO_UNKNOWN;
SCpnt->SCp.sent_command = 0;
SCpnt->SCp.phase = PH_UNDETERMINED;
RESID = SCpnt->request_bufflen;
/* setup scratch area
SCp.ptr : buffer pointer
......@@ -200,7 +212,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCp.phase : current state of the command */
if (SCpnt->use_sg) {
SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
SCpnt->SCp.ptr = SCpnt->SCp.buffer->address;
SCpnt->SCp.ptr = BUFFER_ADDR;
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
} else {
......@@ -219,7 +231,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
}
//DEBUG(0, __FUNCTION__ "() out\n");
//DEBUG(0, __func__ "() out\n");
return 0;
}
......@@ -231,7 +243,7 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
unsigned int base = data->BaseAddress;
unsigned char transfer_mode_reg;
//DEBUG(0, __FUNCTION__ "() enabled=%d\n", enabled);
//DEBUG(0, __func__ "() enabled=%d\n", enabled);
if (enabled != FALSE) {
transfer_mode_reg = TRANSFER_GO | BRAIND;
......@@ -244,31 +256,35 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
}
static void nsphw_init_sync(nsp_hw_data *data)
{
sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
.SyncPeriod = 0,
.SyncOffset = 0
};
int i;
/* setup sync data */
for ( i = 0; i < N_TARGET; i++ ) {
data->Sync[i] = tmp_sync;
}
}
/*
* Initialize Ninja hardware
*/
static int nsphw_init(nsp_hw_data *data)
{
unsigned int base = data->BaseAddress;
int i, j;
sync_data tmp_sync = { SyncNegotiation: SYNC_NOT_YET,
SyncPeriod: 0,
SyncOffset: 0
};
DEBUG(0, __FUNCTION__ "() in base=0x%x\n", base);
DEBUG(0, "%s() in base=0x%x\n", __FUNCTION__, base);
data->ScsiClockDiv = CLOCK_40M;
data->ScsiClockDiv = CLOCK_40M | FAST_20;
data->CurrentSC = NULL;
data->FifoCount = 0;
data->TransferMode = MODE_IO8;
/* setup sync data */
for ( i = 0; i < N_TARGET; i++ ) {
for ( j = 0; j < N_LUN; j++ ) {
data->Sync[i][j] = tmp_sync;
}
}
nsphw_init_sync(data);
/* block all interrupts */
nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
......@@ -321,10 +337,10 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
unsigned int host_id = SCpnt->host->this_id;
unsigned int base = SCpnt->host->io_port;
unsigned char target = SCpnt->target;
int wait_count;
int time_out;
unsigned char phase, arbit;
//DEBUG(0, __FUNCTION__ "()in\n");
//DEBUG(0, __func__ "()in\n");
phase = nsp_index_read(base, SCSIBUSMON);
if(phase != BUSMON_BUS_FREE) {
......@@ -337,14 +353,14 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
SCpnt->SCp.phase = PH_ARBSTART;
nsp_index_write(base, SETARBIT, ARBIT_GO);
wait_count = jiffies + 10 * HZ;
time_out = 1000;
do {
/* XXX: what a stupid chip! */
arbit = nsp_index_read(base, ARBITSTATUS);
//DEBUG(0, " arbit=%d, wait_count=%d\n", arbit, wait_count);
udelay(1); /* hold 1.2us */
} while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
time_before(jiffies, wait_count));
(time_out-- != 0));
if((arbit & ARBIT_WIN) == 0) {
//DEBUG(0, " arbit fail\n");
......@@ -356,13 +372,13 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
//DEBUG(0, " assert SEL line\n");
SCpnt->SCp.phase = PH_SELSTART;
udelay(3);
nsp_index_write(base, SCSIDATALATCH, (1 << host_id) | (1 << target));
nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
udelay(3);
nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
udelay(3);
nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
/* check selection timeout */
nsp_start_timer(SCpnt, data, 1000/51);
......@@ -399,23 +415,21 @@ static struct nsp_sync_table nsp_sync_table_20M[] = {
static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
unsigned char target = SCpnt->target;
unsigned char lun = SCpnt->lun;
sync_data *sync = &(data->Sync[target][lun]);
// unsigned char lun = SCpnt->lun;
sync_data *sync = &(data->Sync[target]);
struct nsp_sync_table *sync_table;
unsigned int period, offset;
int i;
DEBUG(0, __FUNCTION__ "()\n");
/**!**/
DEBUG(0, "%s()\n", __FUNCTION__);
period = sync->SyncPeriod;
offset = sync->SyncOffset;
DEBUG(0, " period=0x%x, offset=0x%x\n", period, offset);
if (data->ScsiClockDiv == CLOCK_20M) {
if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
sync_table = &nsp_sync_table_20M[0];
} else {
sync_table = &nsp_sync_table_40M[0];
......@@ -438,7 +452,6 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
sync->SyncOffset = 0;
sync->SyncRegister = 0;
sync->AckWidth = 0;
sync->SyncNegotiation = SYNC_OK;
return FALSE;
}
......@@ -446,7 +459,6 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
(offset & SYNCREG_OFFSET_MASK);
sync->AckWidth = sync_table->ack_width;
sync->SyncNegotiation = SYNC_OK;
DEBUG(0, " sync_reg=0x%x, ack_width=0x%x\n", sync->SyncRegister, sync->AckWidth);
......@@ -461,7 +473,7 @@ static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time)
{
unsigned int base = SCpnt->host->io_port;
//DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p, time=%d\n", SCpnt, time);
//DEBUG(0, __func__ "() in SCpnt=0x%p, time=%d\n", SCpnt, time);
data->TimerCount = time;
nsp_index_write(base, TIMERCOUNT, time);
}
......@@ -473,21 +485,21 @@ static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
{
unsigned int base = SCpnt->host->io_port;
unsigned char reg;
int count, i = TRUE;
int time_out;
//DEBUG(0, __FUNCTION__ "()\n");
//DEBUG(0, __func__ "()\n");
count = jiffies + HZ;
time_out = 100;
do {
reg = nsp_index_read(base, SCSIBUSMON);
if (reg == 0xff) {
break;
}
} while ((i = time_before(jiffies, count)) && (reg & mask) != 0);
} while ((time_out-- != 0) && (reg & mask) != 0);
if (!i) {
printk(KERN_DEBUG __FUNCTION__ " %s signal off timeut\n", str);
if (time_out == 0) {
printk(KERN_DEBUG "%s: %s signal off timeut\n", __FUNCTION__, str);
}
return 0;
......@@ -501,12 +513,12 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
unsigned char mask)
{
unsigned int base = SCpnt->host->io_port;
int wait_count;
int time_out;
unsigned char phase, i_src;
//DEBUG(0, __FUNCTION__ "() current_phase=0x%x, mask=0x%x\n", current_phase, mask);
//DEBUG(0, __func__ "() current_phase=0x%x, mask=0x%x\n", current_phase, mask);
wait_count = jiffies + HZ;
time_out = 100;
do {
phase = nsp_index_read(base, SCSIBUSMON);
if (phase == 0xff) {
......@@ -522,9 +534,9 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
//DEBUG(0, " ret 1 phase=0x%x\n", phase);
return 1;
}
} while(time_before(jiffies, wait_count));
} while(time_out-- != 0);
//DEBUG(0, __FUNCTION__ " : " __FUNCTION__ " timeout\n");
//DEBUG(0, __func__ " : " __func__ " timeout\n");
return -1;
}
......@@ -539,7 +551,7 @@ static int nsp_xfer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int phase)
int ptr;
int ret;
//DEBUG(0, __FUNCTION__ "()\n");
//DEBUG(0, __func__ "()\n");
for (ptr = 0; len > 0; len --, ptr ++) {
ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
......@@ -574,7 +586,7 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
unsigned int count;
//DEBUG(0, __FUNCTION__ "()\n");
//DEBUG(0, __func__ "()\n");
if (SCpnt->SCp.have_data_in != IO_IN) {
return 0;
......@@ -590,11 +602,11 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
* XXX: NSP_QUIRK
* data phase skip only occures in case of SCSI_LOW_READ
*/
DEBUG(0, " use bypass quirk\n");
SCpnt->SCp.phase = PH_DATA;
nsp_pio_read(SCpnt, data);
nsp_setup_fifo(data, FALSE);
DEBUG(0, " use bypass quirk\n");
return 0;
}
......@@ -606,7 +618,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
unsigned int base = SCpnt->host->io_port;
unsigned char reg;
//DEBUG(0, __FUNCTION__ "()\n");
//DEBUG(0, __func__ "()\n");
nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
......@@ -625,17 +637,18 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
{
unsigned int base = SCpnt->host->io_port;
unsigned int count;
unsigned int l, m, h;
unsigned int l, m, h, dummy;
nsp_index_write(base, POINTERCLR, POINTER_CLEAR);
nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
l = (unsigned int)nsp_read(base, DATAREG);
m = (unsigned int)nsp_read(base, DATAREG);
h = (unsigned int)nsp_read(base, DATAREG);
l = nsp_index_read(base, TRANSFERCOUNT);
m = nsp_index_read(base, TRANSFERCOUNT);
h = nsp_index_read(base, TRANSFERCOUNT);
dummy = nsp_index_read(base, TRANSFERCOUNT);
count = (h << 16) | (m << 8) | (l << 0);
//DEBUG(0, __FUNCTION__ "() =0x%x\n", count);
//DEBUG(0, __func__ "() =0x%x\n", count);
return count;
}
......@@ -649,25 +662,27 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
*/
static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
unsigned int base = SCpnt->host->io_port;
int time_out, i;
unsigned int base = SCpnt->host->io_port;
unsigned long mmio_base = SCpnt->host->base;
long time_out;
int ocount, res;
unsigned char stat, fifo_stat;
ocount = data->FifoCount;
DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d\n", SCpnt, RESID, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
DEBUG(0, "%s() in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d\n",
__FUNCTION__, SCpnt, RESID, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
time_out = jiffies + 10 * HZ;
time_out = 1000;
while ((i = time_before(jiffies,time_out)) &&
while ((time_out-- != 0) &&
(SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
stat = nsp_index_read(base, SCSIBUSMON);
stat &= BUSMON_PHASE_MASK;
res = nsp_fifo_count(SCpnt) - ocount;
res = nsp_fifo_count(SCpnt) - ocount;
//DEBUG(0, " ptr=0x%p this=0x%x ocount=0x%x res=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
if (res == 0) { /* if some data avilable ? */
if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
......@@ -695,9 +710,15 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
case MODE_IO8:
nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
break;
case MODE_MEM32:
res &= ~(BIT(1)|BIT(0)); /* align 4 */
nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
break;
default:
DEBUG(0, "unknown read mode\n");
break;
return;
}
RESID -= res;
......@@ -712,17 +733,19 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
//DEBUG(0, " scatterlist next timeout=%d\n", time_out);
SCpnt->SCp.buffers_residual--;
SCpnt->SCp.buffer++;
SCpnt->SCp.ptr = SCpnt->SCp.buffer->address;
SCpnt->SCp.ptr = BUFFER_ADDR;
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
}
time_out = 1000;
time_out = jiffies + 10 * HZ;
//DEBUG(0, "page: 0x%p, off: 0x%x\n", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
}
}
data->FifoCount = ocount;
if (!i) {
printk(KERN_DEBUG __FUNCTION__ "() pio read timeout resid=%d this_residual=%d buffers_residual=%d\n", RESID, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
if (time_out == 0) {
printk(KERN_DEBUG "%s() pio read timeout resid=%d this_residual=%d buffers_residual=%d\n",
__FUNCTION__, RESID, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
}
DEBUG(0, " read ocount=0x%x\n", ocount);
}
......@@ -733,22 +756,32 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
unsigned int base = SCpnt->host->io_port;
int time_out, i;
unsigned int ocount, res;
unsigned long mmio_base = SCpnt->host->base;
int time_out;
int ocount, res;
unsigned char stat;
ocount = data->FifoCount;
DEBUG(0, __FUNCTION__ "() in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x\n", data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, RESID);
DEBUG(0, "%s() in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x\n", __FUNCTION__, data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, RESID);
time_out = jiffies + 10 * HZ;
time_out = 1000;
while ((i = time_before(jiffies, time_out)) &&
while ((time_out-- != 0) &&
(SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
stat = nsp_index_read(base, SCSIBUSMON);
stat &= BUSMON_PHASE_MASK;
if (stat != BUSPHASE_DATA_OUT) {
DEBUG(0, " phase changed stat=0x%x\n", stat);
res = ocount - nsp_fifo_count(SCpnt);
DEBUG(0, " phase changed stat=0x%x, res=%d\n", stat, res);
/* Put back pointer */
RESID += res;
SCpnt->SCp.ptr -= res;
SCpnt->SCp.this_residual += res;
ocount -= res;
break;
}
......@@ -769,6 +802,12 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
case MODE_IO8:
nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
break;
case MODE_MEM32:
res &= ~(BIT(1)|BIT(0)); /* align 4 */
nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
break;
default:
DEBUG(0, "unknown write mode\n");
break;
......@@ -785,19 +824,18 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
//DEBUG(0, " scatterlist next\n");
SCpnt->SCp.buffers_residual--;
SCpnt->SCp.buffer++;
SCpnt->SCp.ptr = SCpnt->SCp.buffer->address;
SCpnt->SCp.ptr = BUFFER_ADDR;
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
time_out = 1000;
}
time_out = jiffies + 10 * HZ;
}
data->FifoCount = ocount;
if (!i) {
printk(KERN_DEBUG __FUNCTION__ "() pio write timeout resid=%d\n", RESID);
if (time_out == 0) {
printk(KERN_DEBUG "%s() pio write timeout resid=0x%x\n", __FUNCTION__, RESID);
}
//DEBUG(0, " write ocount=%d\n", ocount);
DEBUG(0, " write ocount=0x%x\n", ocount);
}
#undef RFIFO_CRIT
......@@ -810,20 +848,25 @@ static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
unsigned int base = SCpnt->host->io_port;
unsigned char target = SCpnt->target;
unsigned char lun = SCpnt->lun;
sync_data *sync = &(data->Sync[target][lun]);
// unsigned char lun = SCpnt->lun;
sync_data *sync = &(data->Sync[target]);
//DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p\n", SCpnt);
//DEBUG(0, __func__ "() in SCpnt=0x%p\n", SCpnt);
/* setup synch transfer registers */
nsp_index_write(base, SYNCREG, sync->SyncRegister);
nsp_index_write(base, ACKWIDTH, sync->AckWidth);
if (RESID % 4 != 0 ||
RESID <= 256 ) {
if (SCpnt->use_sg == 0 ||
RESID % 4 != 0 ||
RESID <= PAGE_SIZE ) {
data->TransferMode = MODE_IO8;
} else {
} else if (nsp_burst_mode == BURST_MEM32) {
data->TransferMode = MODE_MEM32;
} else if (nsp_burst_mode == BURST_IO32) {
data->TransferMode = MODE_IO32;
} else {
data->TransferMode = MODE_IO8;
}
/* setup pdma fifo */
......@@ -848,24 +891,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
unsigned int base;
unsigned char i_src, irq_phase, phase;
Scsi_Cmnd *tmpSC;
int len;
unsigned char target, lun;
unsigned int *sync_neg;
int i, tmp;
nsp_hw_data *data;
nsp_hw_data *data = dev_id;
//printk("&nsp_data=0x%p, dev_id=0x%p\n", &nsp_data, dev_id);
/* sanity check */
if (&nsp_data != dev_id) {
DEBUG(0, " irq conflict? this can't happen\n");
return;
}
data = dev_id;
if (irq != data->IrqNumber) {
return;
}
base = data->BaseAddress;
//DEBUG(0, " base=0x%x\n", base);
......@@ -874,13 +906,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
*/
nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
i_src = nsp_read(base, IRQSTATUS);
if (i_src == 0xff || (i_src & IRQSTATUS_MASK) == 0) {
//DEBUG(0, " i_src=0x%x\n", i_src);
if ((i_src == 0xff) || ((i_src & IRQSTATUS_MASK) == 0)) {
nsp_write(base, IRQCONTROL, 0);
//DEBUG(0, " no irq\n");
//DEBUG(0, " no irq/shared irq\n");
return;
}
//DEBUG(0, " i_src=0x%x\n", i_src);
/* XXX: IMPORTANT
* Do not read an irq_phase register if no scsi phase interrupt.
......@@ -916,13 +948,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
if (data->CurrentSC == NULL) {
printk(KERN_DEBUG __FUNCTION__ " CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen\n", i_src, phase, irq_phase);
printk(KERN_DEBUG "%s: CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x cannot happen\n", __FUNCTION__, i_src, phase, irq_phase);
return;
} else {
tmpSC = data->CurrentSC;
target = tmpSC->target;
lun = tmpSC->lun;
sync_neg = &(data->Sync[target][lun].SyncNegotiation);
sync_neg = &(data->Sync[target].SyncNegotiation);
}
/*
......@@ -930,10 +962,12 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
*/
if ((i_src & IRQSTATUS_SCSI) != 0) {
if ((irq_phase & SCSI_RESET_IRQ) != 0) {
printk(KERN_DEBUG " " __FUNCTION__ "() bus reset (power off?)\n");
printk(KERN_DEBUG " %s() bus reset (power off?)\n", __FUNCTION__);
*sync_neg = SYNC_NOT_YET;
data->CurrentSC = NULL;
tmpSC->result = DID_RESET << 16;
tmpSC->result = (DID_RESET << 16) |
((tmpSC->SCp.Message & 0xff) << 8) |
((tmpSC->SCp.Status & 0xff) << 0);
tmpSC->scsi_done(tmpSC);
return;
}
......@@ -955,7 +989,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
switch(tmpSC->SCp.phase) {
case PH_SELSTART:
*sync_neg = SYNC_NOT_YET;
//*sync_neg = SYNC_NOT_YET;
if ((phase & BUSMON_BSY) == 0) {
//DEBUG(0, " selection count=%d\n", data->SelectionTimeOut);
if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
......@@ -987,7 +1021,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
case PH_RESELECT:
//DEBUG(0, " phase reselect\n");
*sync_neg = SYNC_NOT_YET;
//*sync_neg = SYNC_NOT_YET;
if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
data->CurrentSC = NULL;
......@@ -1009,16 +1043,18 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
//DEBUG(0, " start scsi seq\n");
/* normal disconnect */
if ((irq_phase & LATCHED_BUS_FREE) != 0) {
//DEBUG(0, " normal disconnect i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase);
if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
(irq_phase & LATCHED_BUS_FREE) != 0 ) {
DEBUG(0, " normal disconnect i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase);
if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
*sync_neg = SYNC_NOT_YET;
//*sync_neg = SYNC_NOT_YET;
data->CurrentSC = NULL;
tmpSC->result = (DID_OK << 16) |
(tmpSC->SCp.Message << 8) |
(tmpSC->SCp.Status << 0);
tmpSC->result = (DID_OK << 16) |
((tmpSC->SCp.Message & 0xff) << 8) |
((tmpSC->SCp.Status & 0xff) << 0);
DEBUG(0, " command complete result=0x%x\n", tmpSC->result);
tmpSC->scsi_done(tmpSC);
return;
}
......@@ -1028,7 +1064,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
/* check unexpected bus free state */
if (phase == 0) {
printk(KERN_DEBUG " " __FUNCTION__ " unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase);
printk(KERN_DEBUG "%s: unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", __FUNCTION__, i_src, phase, irq_phase);
*sync_neg = SYNC_NOT_YET;
data->CurrentSC = NULL;
......@@ -1050,9 +1086,10 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
nsp_nexus(tmpSC, data);
/* write scsi command */
DEBUG(0, " cmd_len=%d\n", tmpSC->cmd_len);
nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
for (len = 0; len < COMMAND_SIZE(tmpSC->cmnd[0]); len++) {
nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[len]);
for (i = 0; i < tmpSC->cmd_len; i++) {
nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
}
nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
break;
......@@ -1084,7 +1121,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC->SCp.phase = PH_STATUS;
tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
//DEBUG(0, " message=0x%x status=0x%x\n", tmpSC->SCp.Message, tmpSC->SCp.Status);
DEBUG(0, " message=0x%x status=0x%x\n", tmpSC->SCp.Message, tmpSC->SCp.Status);
break;
......@@ -1096,26 +1133,24 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC->SCp.phase = PH_MSG_OUT;
data->MsgLen = len = 0;
if (*sync_neg == SYNC_NOT_YET) {
data->Sync[target][lun].SyncPeriod = 0;
data->Sync[target][lun].SyncOffset = 0;
nsp_msg(tmpSC, data);
data->MsgLen = i = 0;
data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
data->MsgBuffer[len] = IDENTIFY(TRUE, lun); len++;
/*
data->MsgBuffer[len] = MSG_EXTENDED; len++;
data->MsgBuffer[len] = 3; len++;
data->MsgBuffer[len] = MSG_EXT_SDTR; len++;
data->MsgBuffer[len] = 0x0c; len++;
data->MsgBuffer[len] = 15; len++;
*/
}
if (len == 0) {
data->MsgBuffer[len] = MSG_NO_OPERATION; len++;
if (*sync_neg == SYNC_NOT_YET) {
data->Sync[target].SyncPeriod = 0;
data->Sync[target].SyncOffset = 0;
/**/
data->MsgBuffer[i] = MSG_EXTENDED; i++;
data->MsgBuffer[i] = 3; i++;
data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
data->MsgBuffer[i] = 0x0c; i++;
data->MsgBuffer[i] = 15; i++;
/**/
}
data->MsgLen = len;
data->MsgLen = i;
nsp_msg(tmpSC, data);
show_message(data);
nsp_message_out(tmpSC, data);
break;
......@@ -1130,16 +1165,26 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC->SCp.phase = PH_MSG_IN;
nsp_message_in(tmpSC, data);
/*
if (data->MsgLen >= 5 &&
data->MsgBuffer[0] == MSG_EXTENDED &&
data->MsgBuffer[1] == 3 &&
data->MsgBuffer[2] == MSG_EXT_SDTR ) {
data->Sync[target][lun].SyncPeriod = data->MsgBuffer[3];
data->Sync[target][lun].SyncOffset = data->MsgBuffer[4];
/**/
if (*sync_neg == SYNC_NOT_YET) {
//printk("%d,%d\n",target,lun);
if (data->MsgLen >= 5 &&
data->MsgBuffer[0] == MSG_EXTENDED &&
data->MsgBuffer[1] == 3 &&
data->MsgBuffer[2] == MSG_EXT_SDTR ) {
data->Sync[target].SyncPeriod = data->MsgBuffer[3];
data->Sync[target].SyncOffset = data->MsgBuffer[4];
//printk("sync ok, %d %d\n", data->MsgBuffer[3], data->MsgBuffer[4]);
*sync_neg = SYNC_OK;
} else {
data->Sync[target].SyncPeriod = 0;
data->Sync[target].SyncOffset = 0;
*sync_neg = SYNC_NG;
}
nsp_msg(tmpSC, data);
}
*/
/**/
/* search last messeage byte */
tmp = -1;
......@@ -1163,7 +1208,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
break;
}
//DEBUG(0, __FUNCTION__ "() out\n");
//DEBUG(0, __func__ "() out\n");
return;
timer_out:
......@@ -1183,41 +1228,52 @@ static int nsp_detect(Scsi_Host_Template *sht)
struct Scsi_Host *host; /* registered host structure */
nsp_hw_data *data = &nsp_data;
DEBUG(0, __FUNCTION__ " this_id=%d\n", sht->this_id);
DEBUG(0, "%s: this_id=%d\n", __FUNCTION__, sht->this_id);
request_region(data->BaseAddress, data->NumAddress, "nsp_cs");
host = scsi_register(sht, 0);
host->io_port = data->BaseAddress;
host->unique_id = data->BaseAddress;
host->io_port = data->BaseAddress;
host->n_io_port = data->NumAddress;
host->irq = data->IrqNumber;
host->dma_channel = 0xff; /* not use dms */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
host->base = data->MmioAddress; /* kernel 2.4 */
#else
host->base = (char *)(data->MmioAddress); /* 2.2 */
#endif
spin_lock_init(&(data->Lock));
snprintf(data->nspinfo,
sizeof(data->nspinfo),
"NinjaSCSI-3/32Bi Driver $Revision: 1.4 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
host->io_port, host->io_port + host->n_io_port - 1,
host->base,
host->irq);
data->nspinfo[sizeof(data->nspinfo) - 1] = '\0';
sht->name = data->nspinfo;
sprintf(nspinfo,
/* Buffer size is 100 bytes */
/* 0 1 2 3 4 5 6 7 8 9 0*/
/* 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890*/
"NinjaSCSI-3/32Bi Driver $Revision: 1.42 $, I/O 0x%04lx-0x%04lx IRQ %2d",
host->io_port, host->io_port + host->n_io_port,
host->irq);
sht->name = nspinfo;
DEBUG(0, "%s: end\n", __FUNCTION__);
DEBUG(0, __FUNCTION__ " end\n");
//MOD_INC_USE_COUNT;
return 1; /* detect done. */
}
/* nsp_cs requires own release handler because its uses dev_id (=data) */
static int nsp_release(struct Scsi_Host *shpnt)
{
nsp_hw_data *data = &nsp_data;
//nsp_hw_data *data = &nsp_data;
/* PCMCIA Card Service dose same things */
//if (shpnt->irq) {
// free_irq(shpnt->irq, data);
//}
//if (shpnt->io_port) {
// release_region(shpnt->io_port, shpnt->n_io_port);
//}
//MOD_DEC_USE_COUNT;
if (shpnt->irq) {
free_irq(shpnt->irq, data);
}
if (shpnt->io_port && shpnt->n_io_port) {
release_region(shpnt->io_port, shpnt->n_io_port);
}
return 0;
}
......@@ -1226,25 +1282,152 @@ static int nsp_release(struct Scsi_Host *shpnt)
/*----------------------------------------------------------------*/
static const char *nsp_info(struct Scsi_Host *shpnt)
{
return nspinfo;
nsp_hw_data *data = &nsp_data;
return data->nspinfo;
}
#undef SPRINTF
#define SPRINTF(args...) \
do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
static int nsp_proc_info(char *buffer,
char **start,
off_t offset,
int length,
int hostno,
int inout)
{
int id;
char *pos = buffer;
int thislength;
int speed;
unsigned long flags;
nsp_hw_data *data = &nsp_data;
struct Scsi_Host *host;
if (inout) {
return -EINVAL;
}
host = scsi_host_hn_get(hostno);
SPRINTF("NinjaSCSI status\n\n");
SPRINTF("Driver version: $Revision: 1.4 $\n");
SPRINTF("SCSI host No.: %d\n", hostno);
SPRINTF("IRQ: %d\n", host->irq);
SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
SPRINTF("MMIO(virtual address): 0x%lx\n", host->base);
SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
SPRINTF("burst transfer mode: ");
switch (nsp_burst_mode) {
case BURST_IO8:
SPRINTF("io8");
break;
case BURST_IO32:
SPRINTF("io32");
break;
case BURST_MEM32:
SPRINTF("mem32");
break;
default:
SPRINTF("???");
break;
}
SPRINTF("\n");
spin_lock_irqsave(&(data->Lock), flags);
SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
spin_unlock_irqrestore(&(data->Lock), flags);
SPRINTF("SDTR status\n");
for(id = 0; id < N_TARGET; id++) {
SPRINTF("id %d: ", id);
if (id == host->this_id) {
SPRINTF("----- NinjaSCSI-3 host adapter\n");
continue;
}
switch(data->Sync[id].SyncNegotiation) {
case SYNC_OK:
SPRINTF(" sync");
break;
case SYNC_NG:
SPRINTF("async");
break;
case SYNC_NOT_YET:
SPRINTF(" none");
break;
default:
SPRINTF("?????");
break;
}
if (data->Sync[id].SyncPeriod != 0) {
speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
SPRINTF(" transfer %d.%dMB/s, offset %d",
speed / 1000,
speed % 1000,
data->Sync[id].SyncOffset
);
}
SPRINTF("\n");
}
thislength = pos - (buffer + offset);
if(thislength < 0) {
*start = 0;
return 0;
}
thislength = MIN(thislength, length);
*start = buffer + offset;
return thislength;
}
#undef SPRINTF
/*---------------------------------------------------------------*/
/* error handler */
/*---------------------------------------------------------------*/
static int nsp_reset(Scsi_Cmnd *SCpnt, unsigned int why)
static int nsp_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
{
DEBUG(0, __FUNCTION__ " SCpnt=0x%p why=%d\n", SCpnt, why);
nsp_hw_data *data = &nsp_data;
int ret = 0;
nsp_eh_bus_reset(SCpnt);
DEBUG(0, "%s: SCpnt=0x%p why=%d\n", __FUNCTION__, SCpnt, reset_flags);
return SCSI_RESET_SUCCESS;
if (reset_flags & SCSI_RESET_SUGGEST_BUS_RESET) {
nsp_eh_bus_reset(SCpnt);
ret |= SCSI_RESET_BUS_RESET;
}
if (reset_flags & SCSI_RESET_SUGGEST_HOST_RESET) {
nsp_eh_host_reset(SCpnt);
ret |= SCSI_RESET_HOST_RESET;
}
if (ret != 0) {
return SCSI_RESET_SUCCESS | ret;
} else {
nsphw_init_sync(data);
return SCSI_RESET_PUNT;
}
}
static int nsp_abort(Scsi_Cmnd *SCpnt)
{
DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
DEBUG(0, "%s: SCpnt=0x%p\n", __FUNCTION__, SCpnt);
nsp_eh_host_reset(SCpnt);
nsp_eh_bus_reset(SCpnt);
return SCSI_ABORT_SUCCESS;
......@@ -1255,28 +1438,29 @@ static int nsp_abort(Scsi_Cmnd *SCpnt)
return FAILED;
}*/
/*
static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
{
DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
DEBUG(0, "%s: SCpnt=0x%p\n", __FUNCTION__, SCpnt);
nsp_eh_bus_reset(SCpnt);
return SUCCESS;
}
return nsp_eh_bus_reset(SCpnt);
}*/
/*
static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
{
DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
DEBUG(0, "%s: SCpnt=0x%p\n", __FUNCTION__, SCpnt);
return FAILED;
}
}*/
static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
{
nsp_hw_data *data = &nsp_data;
unsigned int base = SCpnt->host->io_port;
int i;
DEBUG(0, __FUNCTION__ "() SCpnt=0x%p base=0x%x\n", SCpnt, base);
DEBUG(0, "%s() SCpnt=0x%p base=0x%x\n", __FUNCTION__, SCpnt, base);
nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
......@@ -1289,6 +1473,8 @@ static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
nsphw_init_sync(data);
return SUCCESS;
}
......@@ -1296,17 +1482,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
{
nsp_hw_data *data = &nsp_data;
DEBUG(0, __FUNCTION__ "\n");
DEBUG(0, "%s\n", __FUNCTION__);
nsphw_init(data);
return nsp_eh_bus_reset(SCpnt);
return SUCCESS;
}
/**********************************************************************
PCMCIA functions
*********************************************************************/
**********************************************************************/
/*====================================================================*/
static void cs_error(client_handle_t handle, int func, int ret)
......@@ -1331,7 +1517,7 @@ static dev_link_t *nsp_cs_attach(void)
dev_link_t *link;
int ret, i;
DEBUG(0, __FUNCTION__ "()\n");
DEBUG(0, "%s()\n", __FUNCTION__);
/* Create new SCSI device */
info = kmalloc(sizeof(*info), GFP_KERNEL);
......@@ -1359,8 +1545,15 @@ static dev_link_t *nsp_cs_attach(void)
link->irq.IRQInfo2 |= 1 << irq_list[i];
}
}
/* IRQ $B$N3NJ]$O$3$3$G(B PCMCIA $B$N4X?t$rMQ$$$F9T$J$&$N$G(B
* host->hostdata $B$r(B irq.Instance $B$KBeF~$G$-$J$$!#(B
* host->hostdata $B$,;H$($l$PJ#?t$N(B NinjaSCSI $B$,(B
* $B;HMQ$G$-$k$N$@$,!#(B
*/
link->irq.Handler = &nspintr;
link->irq.Instance = &nsp_data;
link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
/* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ;
......@@ -1402,7 +1595,7 @@ static void nsp_cs_detach(dev_link_t *link)
{
dev_link_t **linkp;
DEBUG(0, __FUNCTION__ "(0x%p)\n", link);
DEBUG(0, "%s(0x%p)\n", __FUNCTION__, link);
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
......@@ -1414,7 +1607,7 @@ static void nsp_cs_detach(dev_link_t *link)
return;
}
del_timer(&link->release);
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
nsp_cs_release((u_long)link);
if (link->state & DEV_STALE_CONFIG) {
......@@ -1431,6 +1624,7 @@ static void nsp_cs_detach(dev_link_t *link)
/* Unlink device structure, free bits */
*linkp = link->next;
kfree(link->priv);
link->priv = NULL;
} /* nsp_cs_detach */
......@@ -1452,15 +1646,20 @@ static void nsp_cs_config(dev_link_t *link)
scsi_info_t *info = link->priv;
tuple_t tuple;
cisparse_t parse;
int i, last_ret, last_fn;
int last_ret, last_fn;
u_char tuple_data[64];
config_info_t conf;
win_req_t req;
memreq_t map;
cistpl_cftable_entry_t dflt = { 0 };
Scsi_Device *dev;
dev_node_t **tail, *node;
struct Scsi_Host *host;
nsp_hw_data *data = &nsp_data;
DEBUG(0, __FUNCTION__ "() in\n");
DEBUG(0, "%s() in\n", __FUNCTION__);
tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0;
......@@ -1474,7 +1673,6 @@ static void nsp_cs_config(dev_link_t *link)
link->conf.Present = parse.config.rmask[0];
/* Configure card */
driver_template.module = &__this_module;
link->state |= DEV_CONFIG;
/* Look up the current Vcc */
......@@ -1484,44 +1682,130 @@ static void nsp_cs_config(dev_link_t *link)
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, handle, &tuple);
while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
CFG_CHECK(GetTupleData, handle, &tuple);
CFG_CHECK(ParseTuple, handle, &tuple, &parse);
link->conf.ConfigIndex = parse.cftable_entry.index;
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
i = CardServices(RequestIO, handle, &link->io);
if (i == CS_SUCCESS) {
break;
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
if (cfg->index == 0) { goto next_entry; }
link->conf.ConfigIndex = cfg->index;
/* Does this card need audio output? */
if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
goto next_entry;
}
} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
goto next_entry;
}
}
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) {
link->conf.Vpp1 = link->conf.Vpp2 =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
} else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) {
link->conf.Vpp1 = link->conf.Vpp2 =
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
}
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
link->conf.Attributes |= CONF_ENABLE_IRQ;
}
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
CFG_CHECK(RequestIO, link->handle, &link->io);
}
if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
cistpl_mem_t *mem =
(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
req.Attributes |= WIN_ENABLE;
req.Base = mem->win[0].host_addr;
req.Size = mem->win[0].len;
if (req.Size < 0x1000)
req.Size = 0x1000;
req.AccessSpeed = 0;
link->win = (window_handle_t)link->handle;
CFG_CHECK(RequestWindow, &link->win, &req);
map.Page = 0; map.CardOffset = mem->win[0].card_addr;
CFG_CHECK(MapMemPage, link->win, &map);
data->MmioAddress = (u_long)ioremap_nocache(req.Base, req.Size);
}
/* If we got this far, we're cool! */
break;
next_entry:
DEBUG(0, __FUNCTION__ " next\n");
DEBUG(0, "%s next\n", __FUNCTION__);
if (link->io.NumPorts1)
CardServices(ReleaseIO, link->handle, &link->io);
CS_CHECK(GetNextTuple, handle, &tuple);
}
CS_CHECK(RequestIRQ, handle, &link->irq);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
CS_CHECK(RequestIRQ, link->handle, &link->irq);
CS_CHECK(RequestConfiguration, handle, &link->conf);
/* A bad hack... */
release_region(link->io.BasePort1, link->io.NumPorts1);
if (free_ports) {
if (link->io.BasePort1)
release_region(link->io.BasePort1, link->io.NumPorts1);
if (link->io.BasePort2)
release_region(link->io.BasePort2, link->io.NumPorts2);
}
/* Set port and IRQ */
data->BaseAddress = link->io.BasePort1;
data->NumAddress = link->io.NumPorts1;
data->IrqNumber = link->irq.AssignedIRQ;
data->BaseAddress = link->io.BasePort1;
data->NumAddress = link->io.NumPorts1;
data->IrqNumber = link->irq.AssignedIRQ;
DEBUG(0, __FUNCTION__ " I/O[0x%x+0x%x] IRQ %d\n",
DEBUG(0, "%s I/O[0x%x+0x%x] IRQ %d\n",
__FUNCTION__,
data->BaseAddress, data->NumAddress, data->IrqNumber);
if(nsphw_init(data) == FALSE) {
goto cs_failed;
}
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_register_host(&driver_template);
#else
scsi_register_module(MODULE_SCSI_HA, &driver_template);
#endif
DEBUG(0, "GET_SCSI_INFO\n");
tail = &link->dev;
info->ndev = 0;
for (host = scsi_host_get_next(NULL); host;
host = scsi_host_get_next(host))
host = scsi_host_get_next(host)) {
if (host->hostt == &driver_template) {
for (dev = host->host_queue; dev != NULL; dev = dev->next) {
u_long arg[2], id;
......@@ -1575,6 +1859,12 @@ static void nsp_cs_config(dev_link_t *link)
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1);
}
if (link->io.NumPorts2)
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
link->io.BasePort2+link->io.NumPorts2-1);
if (link->win)
printk(", mem 0x%06lx-0x%06lx", req.Base,
req.Base+req.Size-1);
printk("\n");
link->state &= ~DEV_CONFIG_PENDING;
......@@ -1598,7 +1888,7 @@ static void nsp_cs_release(u_long arg)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(0, __FUNCTION__ "(0x%p)\n", link);
DEBUG(0, "%s(0x%p)\n", __FUNCTION__, link);
/*
* If the device is currently in use, we won't release until it
......@@ -1612,10 +1902,15 @@ static void nsp_cs_release(u_long arg)
}
/* Unlink the device chain */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_unregister_host(&driver_template);
#else
scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
#endif
link->dev = NULL;
if (link->win) {
iounmap((void *)(nsp_data.MmioAddress));
CardServices(ReleaseWindow, link->win);
}
CardServices(ReleaseConfiguration, link->handle);
......@@ -1645,14 +1940,15 @@ static void nsp_cs_release(u_long arg)
the card is still present.
======================================================================*/
static int nsp_cs_event(event_t event,
int priority,
event_callback_args_t *args)
static int nsp_cs_event(event_t event,
int priority,
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
scsi_info_t *info = link->priv;
Scsi_Cmnd tmp;
DEBUG(1, __FUNCTION__ "(0x%06x)\n", event);
DEBUG(1, "%s(0x%06x)\n", __FUNCTION__, event);
switch (event) {
case CS_EVENT_CARD_REMOVAL:
......@@ -1688,20 +1984,21 @@ static int nsp_cs_event(event_t event,
case CS_EVENT_CARD_RESET:
DEBUG(0, " event: reset\n");
if (link->state & DEV_CONFIG) {
Scsi_Cmnd tmp;
CardServices(RequestConfiguration, link->handle, &link->conf);
tmp.host = info->host;
nsp_eh_host_reset(&tmp);
}
info->stop = 0;
tmp.host = info->host;
nsp_eh_host_reset(&tmp);
nsp_eh_bus_reset(&tmp);
break;
default:
DEBUG(0, " event: unknown\n");
break;
}
DEBUG(0, __FUNCTION__ " end\n");
DEBUG(0, "%s end\n", __FUNCTION__);
return 0;
} /* nsp_cs_event */
......@@ -1712,7 +2009,7 @@ static int __init nsp_cs_init(void)
{
servinfo_t serv;
DEBUG(0, __FUNCTION__ "() in\n");
DEBUG(0, "%s() in\n", __FUNCTION__);
DEBUG(0, "%s\n", version);
CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) {
......@@ -1722,14 +2019,14 @@ static int __init nsp_cs_init(void)
}
register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
DEBUG(0, __FUNCTION__ "() out\n");
DEBUG(0, "%s() out\n", __FUNCTION__);
return 0;
}
static void __exit nsp_cs_cleanup(void)
{
DEBUG(0, __FUNCTION__ "() unloading\n");
DEBUG(0, "%s() unloading\n", __FUNCTION__);
unregister_pcmcia_driver(&dev_info);
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG) {
......@@ -1739,8 +2036,8 @@ static void __exit nsp_cs_cleanup(void)
}
}
module_init(nsp_cs_init);
module_exit(nsp_cs_cleanup);
module_init(nsp_cs_init)
module_exit(nsp_cs_cleanup)
/*
*
......
......@@ -10,13 +10,13 @@
=========================================================*/
/* $Id: nsp_cs.h,v 1.27 2001/09/10 10:31:13 elca Exp $ */
/* $Id: nsp_cs.h,v 1.3 2002/10/10 11:07:52 elca Exp $ */
#ifndef __nsp_cs__
#define __nsp_cs__
/* for debugging */
/*#define PCMCIA_DEBUG 9*/
//#define PCMCIA_DEBUG 9
/*
#define static
......@@ -27,11 +27,11 @@
* Some useful macros...
*/
#define Number(arr) ((int) (sizeof(arr) / sizeof(arr[0])))
#define BIT(x) (1<<(x))
#define BIT(x) (1L << (x))
#define MIN(a,b) ((a) > (b) ? (b) : (a))
/* SCSI initiator must be 7 */
#define SCSI_INITIATOR_ID 7
/* SCSI initiator must be ID 7 */
#define NSP_INITIATOR_ID 7
#define NSP_SELTIMEOUT 200
......@@ -73,6 +73,7 @@
#define CLOCKDIV 0x11
# define CLOCK_40M 0x02
# define CLOCK_20M 0x01
# define FAST_20 BIT(2)
#define TERMPWRCTRL 0x13
# define POWER_ON BIT(0)
......@@ -133,6 +134,9 @@
# define REQ_COUNTER_CLEAR BIT(2)
# define HOST_COUNTER_CLEAR BIT(3)
# define READ_SOURCE 0x30
# define ACK_COUNTER (0)
# define REQ_COUNTER (BIT(4))
# define HOST_COUNTER (BIT(5))
#define TRANSFERCOUNT 0x1E /* R */
......@@ -222,11 +226,14 @@ typedef struct _sync_data {
unsigned char AckWidth;
} sync_data;
typedef struct _nsp_data {
typedef struct _nsp_hw_data {
unsigned int BaseAddress;
unsigned int NumAddress;
unsigned int IrqNumber;
unsigned long MmioAddress;
#define NSP_MMIO_OFFSET 0x0800
unsigned char ScsiClockDiv;
unsigned char TransferMode;
......@@ -238,9 +245,9 @@ typedef struct _nsp_data {
int FifoCount;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
int Residual;
#define RESID data->Residual
#define RESID (data->Residual)
#else
#define RESID SCpnt->resid
#define RESID (SCpnt->resid)
#endif
#define MSGBUF_SIZE 20
......@@ -248,10 +255,20 @@ typedef struct _nsp_data {
int MsgLen;
#define N_TARGET 8
#define N_LUN 8
sync_data Sync[N_TARGET][N_LUN];
sync_data Sync[N_TARGET];
char nspinfo[110]; /* description */
spinlock_t Lock;
} nsp_hw_data;
/* scatter-gather table */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
# define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset))
#else
# define BUFFER_ADDR SCpnt->SCp.buffer->address
#endif
static void nsp_cs_release(u_long arg);
static int nsp_cs_event(event_t event, int priority, event_callback_args_t *args);
......@@ -263,14 +280,16 @@ static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time);
static int nsp_detect(Scsi_Host_Template * );
static int nsp_release(struct Scsi_Host *shpnt);
static const char * nsp_info(struct Scsi_Host *shpnt);
static const char *nsp_info(struct Scsi_Host *shpnt);
static int nsp_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout);
static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
static int nsp_abort(Scsi_Cmnd *);
static int nsp_reset(Scsi_Cmnd *, unsigned int);
static int nsp_eh_abort(Scsi_Cmnd * SCpnt);
static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);
/*static int nsp_eh_abort(Scsi_Cmnd * SCpnt);*/
/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/
static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt);
static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt);
......@@ -294,17 +313,19 @@ static void show_message(nsp_hw_data *data);
* SCSI phase
*/
enum _scsi_phase {
PH_UNDETERMINED,
PH_ARBSTART,
PH_SELSTART,
PH_SELECTED,
PH_COMMAND,
PH_DATA,
PH_STATUS,
PH_MSG_IN,
PH_MSG_OUT,
PH_DISCONNECT,
PH_RESELECT
PH_UNDETERMINED ,
PH_ARBSTART ,
PH_SELSTART ,
PH_SELECTED ,
PH_COMMAND ,
PH_DATA ,
PH_STATUS ,
PH_MSG_IN ,
PH_MSG_OUT ,
PH_DISCONNECT ,
PH_RESELECT ,
PH_ABORT ,
PH_RESET
};
enum _data_in_out {
......@@ -313,11 +334,19 @@ enum _data_in_out {
IO_OUT
};
enum _burst_mode {
BURST_IO8 = 0,
BURST_IO32,
BURST_MEM32
};
/* SCSI messaage */
#define MSG_COMMAND_COMPLETE 0x00
#define MSG_EXTENDED 0x01
#define MSG_ABORT 0x06
#define MSG_NO_OPERATION 0x08
#define MSG_BUS_DEVICE_RESET 0x0c
#define MSG_EXT_SDTR 0x01
......
......@@ -6,7 +6,7 @@
the GNU General Public License.
=========================================================================*/
/* $Id: nsp_debug.c,v 1.8 2001/09/07 04:32:28 elca Exp $ */
/* $Id: nsp_debug.c,v 1.2 2002/09/20 04:06:58 gotom Exp $ */
/*
* Show the command data of a command
......@@ -87,14 +87,21 @@ static void print_opcodek(unsigned char opcode)
static void print_commandk (unsigned char *command)
{
int i,s;
int i, s;
printk(KERN_DEBUG);
print_opcodek(command[0]);
/*printk(KERN_DEBUG __FUNCTION__ " ");*/
for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) {
if ((command[0] >> 5) == 6 ||
(command[0] >> 5) == 7 ) {
s = 12; /* vender specific */
} else {
s = COMMAND_SIZE(command[0]);
}
for ( i = 1; i < s; ++i) {
printk("%02x ", command[i]);
}
switch (COMMAND_SIZE(command[0])) {
switch (s) {
case 6:
printk("LBA=%d len=%d",
(((unsigned int)command[1] & 0x0f) << 16) |
......
......@@ -7,7 +7,7 @@
*/
/* $Id: nsp_io.h,v 1.9 2001/09/07 04:32:42 elca Exp $ */
/* $Id: nsp_io.h,v 1.2 2002/09/20 04:06:58 gotom Exp $ */
#ifndef __NSP_IO_H__
#define __NSP_IO_H__
......@@ -76,7 +76,7 @@ static inline void nsp_fifo8_read(unsigned int base,
void *buf,
unsigned long count)
{
//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx\n", buf, count);
/*DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx\n", buf, count);*/
nsp_multi_read_1(base, FIFODATA, buf, count);
}
......@@ -172,5 +172,103 @@ static inline void nsp_fifo32_write(unsigned int base,
nsp_multi_write_4(base, FIFODATA, buf, count);
}
/*====================================================================*/
static inline void nsp_mmio_write(unsigned long base,
unsigned int index,
unsigned char val)
{
unsigned char *ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + index);
writeb(val, ptr);
}
static inline unsigned char nsp_mmio_read(unsigned long base,
unsigned int index)
{
unsigned char *ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + index);
return readb(ptr);
}
/*-----------*/
static inline unsigned char nsp_mmio_index_read(unsigned long base,
unsigned int reg)
{
unsigned char *index_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + INDEXREG);
unsigned char *data_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + DATAREG);
writeb((unsigned char)reg, index_ptr);
return readb(data_ptr);
}
static inline void nsp_mmio_index_write(unsigned long base,
unsigned int reg,
unsigned char val)
{
unsigned char *index_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + INDEXREG);
unsigned char *data_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + DATAREG);
writeb((unsigned char)reg, index_ptr);
writeb(val, data_ptr);
}
/* read 32bit FIFO */
static inline void nsp_mmio_multi_read_4(unsigned long base,
unsigned int Register,
void *buf,
unsigned long count)
{
unsigned long *ptr = (unsigned long *)(base + Register);
unsigned long *tmp = (unsigned long *)buf;
int i;
//printk("base 0x%0lx ptr 0x%p\n",base,ptr);
for (i = 0; i < count; i++) {
*tmp = readl(ptr);
//printk("<%d,%p,%p,%lx>", i, ptr, tmp, *tmp);
tmp++;
}
}
static inline void nsp_mmio_fifo32_read(unsigned int base,
void *buf,
unsigned long count)
{
//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count);
nsp_mmio_multi_read_4(base, FIFODATA, buf, count);
}
static inline void nsp_mmio_multi_write_4(unsigned long base,
unsigned int Register,
void *buf,
unsigned long count)
{
unsigned long *ptr = (unsigned long *)(base + Register);
unsigned long *tmp = (unsigned long *)buf;
int i;
//printk("base 0x%0lx ptr 0x%p\n",base,ptr);
for (i = 0; i < count; i++) {
writel(*tmp, ptr);
//printk("<%d,%p,%p,%lx>", i, ptr, tmp, *tmp);
tmp++;
}
}
static inline void nsp_mmio_fifo32_write(unsigned int base,
void *buf,
unsigned long count)
{
//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count);
nsp_mmio_multi_write_4(base, FIFODATA, buf, count);
}
#endif
/* end */
......@@ -6,7 +6,7 @@
the GNU General Public License.
*/
/* $Id: nsp_message.c,v 1.7 2001/09/07 04:33:01 elca Exp $ */
/* $Id: nsp_message.c,v 1.2 2002/09/20 04:06:58 gotom Exp $ */
static void nsp_message_in(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
......@@ -64,7 +64,7 @@ static void nsp_message_out(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
DEBUG(0, " msgout loop\n");
do {
if (nsp_xfer(SCpnt, data, BUSPHASE_MESSAGE_OUT)) {
printk(KERN_DEBUG " " __FUNCTION__ " msgout: xfer short\n");
printk(KERN_DEBUG " %s msgout: xfer short\n", __FUNCTION__);
}
/* catch a next signal */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment