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> 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.2.0 Support 32bit PIO mode
Ver.1.1.2 Fix for scatter list buffer exceeds Ver.1.1.2 Fix for scatter list buffer exceeds
Ver.1.1 Support scatter list Ver.1.1 Support scatter list
...@@ -23,7 +25,7 @@ ...@@ -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 #ifdef NSP_KERNEL_2_2
#include <pcmcia/config.h> #include <pcmcia/config.h>
...@@ -39,7 +41,6 @@ ...@@ -39,7 +41,6 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/major.h> #include <linux/major.h>
...@@ -51,7 +52,6 @@ ...@@ -51,7 +52,6 @@
#include <../drivers/scsi/scsi.h> #include <../drivers/scsi/scsi.h>
#include <../drivers/scsi/hosts.h> #include <../drivers/scsi/hosts.h>
#include <../drivers/scsi/sd.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
...@@ -60,20 +60,24 @@ ...@@ -60,20 +60,24 @@
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
#include <pcmcia/cs.h> #include <pcmcia/cs.h>
#include <pcmcia/cistpl.h> #include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h> #include <pcmcia/ds.h>
#include <pcmcia/bus_ops.h>
#include "nsp_cs.h" #include "nsp_cs.h"
MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>"); 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"); MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#endif
#ifdef PCMCIA_DEBUG #ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG; static int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i"); MODULE_PARM(pc_debug, "i");
MODULE_PARM_DESC(pc_debug, "set debug level"); 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) #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
#else #else
#define DEBUG(n, args...) /* */ #define DEBUG(n, args...) /* */
...@@ -108,48 +112,56 @@ static struct proc_dir_entry proc_scsi_nsp = { ...@@ -108,48 +112,56 @@ static struct proc_dir_entry proc_scsi_nsp = {
static unsigned int irq_mask = 0xffff; static unsigned int irq_mask = 0xffff;
MODULE_PARM(irq_mask, "i"); 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 }; static int irq_list[4] = { -1 };
MODULE_PARM(irq_list, "1-4i"); 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)");
/*----------------------------------------------------------------*/ static int nsp_burst_mode = 2;
/* driver state info, local to driver */ MODULE_PARM(nsp_burst_mode, "i");
static char nspinfo[100]; /* description */ 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 */ /* /usr/src/linux/drivers/scsi/hosts.h */
static Scsi_Host_Template driver_template = { static Scsi_Host_Template driver_template = {
/* next: NULL,*/ /* .next = NULL,*/
#if (KERNEL_VERSION(2,3,99) > LINUX_VERSION_CODE) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
proc_dir: &proc_scsi_nsp, /* kernel 2.2 */ .proc_name = "nsp_cs", /* kernel 2.4 */
#else #else
proc_name: "nsp_cs", /* kernel 2.4 */ .proc_dir = &proc_scsi_nsp, /* kernel 2.2 */
#endif #endif
/* proc_info: NULL,*/ .proc_info = nsp_proc_info,
name: "WorkBit NinjaSCSI-3/32Bi", .name = "WorkBit NinjaSCSI-3/32Bi",
detect: nsp_detect, .detect = nsp_detect,
release: nsp_release, .release = nsp_release,
info: nsp_info, .info = nsp_info,
/* command: NULL,*/ /* .command = NULL,*/
queuecommand: nsp_queuecommand, .queuecommand = nsp_queuecommand,
/* eh_strategy_handler: nsp_eh_strategy,*/ /* .eh_strategy_handler = nsp_eh_strategy,*/
eh_abort_handler: nsp_eh_abort, /* .eh_abort_handler = nsp_eh_abort,*/
eh_device_reset_handler: nsp_eh_device_reset, /* .eh_device_reset_handler = nsp_eh_device_reset,*/
eh_bus_reset_handler: nsp_eh_bus_reset, .eh_bus_reset_handler = nsp_eh_bus_reset,
eh_host_reset_handler: nsp_eh_host_reset, .eh_host_reset_handler = nsp_eh_host_reset,
abort: nsp_abort, .abort = nsp_abort,
reset: nsp_reset, .reset = nsp_reset,
/* slave_attach: NULL,*/ /* .slave_attach = NULL,*/
/* bios_param: NULL,*/ /* .bios_param = NULL,*/
can_queue: 1, .can_queue = 1,
this_id: SCSI_INITIATOR_ID, .this_id = NSP_INITIATOR_ID,
sg_tablesize: SG_ALL, .sg_tablesize = SG_ALL,
cmd_per_lun: 1, .cmd_per_lun = 1,
/* present: 0,*/ /* .present = 0,*/
/* unchecked_isa_dma: 0,*/ /* .unchecked_isa_dma = 0,*/
use_clustering: DISABLE_CLUSTERING, .use_clustering = DISABLE_CLUSTERING,
/* emulated: 0,*/ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
.use_new_eh_code = 1,
#endif
/* .emulated = 0,*/
}; };
static dev_link_t *dev_list = NULL; static dev_link_t *dev_list = NULL;
...@@ -162,18 +174,18 @@ static nsp_hw_data nsp_data; ...@@ -162,18 +174,18 @@ static nsp_hw_data nsp_data;
static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{ {
#ifdef PCMCIA_DEBUG #ifdef PCMCIA_DEBUG
//unsigned int host_id = SCpnt->host->this_id; /*unsigned int host_id = SCpnt->host->this_id;*/
//unsigned int base = SCpnt->host->io_port; /*unsigned int base = SCpnt->host->io_port;*/
unsigned char target = SCpnt->target; unsigned char target = SCpnt->target;
#endif #endif
nsp_hw_data *data = &nsp_data; 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", DEBUG(0, "%s() 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); __FUNCTION__, SCpnt, target, SCpnt->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
//DEBUG(0, " before CurrentSC=0x%p\n", data->CurrentSC); //DEBUG(0, " before CurrentSC=0x%p\n", data->CurrentSC);
if(data->CurrentSC != NULL) { 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; data->CurrentSC = NULL;
SCpnt->result = DID_BAD_TARGET << 16; SCpnt->result = DID_BAD_TARGET << 16;
done(SCpnt); done(SCpnt);
...@@ -184,13 +196,13 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -184,13 +196,13 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt->scsi_done = done; SCpnt->scsi_done = done;
data->CurrentSC = SCpnt; data->CurrentSC = SCpnt;
RESID = SCpnt->request_bufflen;
SCpnt->SCp.Status = -1; SCpnt->SCp.Status = CHECK_CONDITION;
SCpnt->SCp.Message = -1; SCpnt->SCp.Message = 0;
SCpnt->SCp.have_data_in = IO_UNKNOWN; SCpnt->SCp.have_data_in = IO_UNKNOWN;
SCpnt->SCp.sent_command = 0; SCpnt->SCp.sent_command = 0;
SCpnt->SCp.phase = PH_UNDETERMINED; SCpnt->SCp.phase = PH_UNDETERMINED;
RESID = SCpnt->request_bufflen;
/* setup scratch area /* setup scratch area
SCp.ptr : buffer pointer SCp.ptr : buffer pointer
...@@ -200,7 +212,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -200,7 +212,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCp.phase : current state of the command */ SCp.phase : current state of the command */
if (SCpnt->use_sg) { if (SCpnt->use_sg) {
SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer; 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.this_residual = SCpnt->SCp.buffer->length;
SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
} else { } else {
...@@ -219,7 +231,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -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; return 0;
} }
...@@ -231,7 +243,7 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled) ...@@ -231,7 +243,7 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
unsigned int base = data->BaseAddress; unsigned int base = data->BaseAddress;
unsigned char transfer_mode_reg; unsigned char transfer_mode_reg;
//DEBUG(0, __FUNCTION__ "() enabled=%d\n", enabled); //DEBUG(0, __func__ "() enabled=%d\n", enabled);
if (enabled != FALSE) { if (enabled != FALSE) {
transfer_mode_reg = TRANSFER_GO | BRAIND; transfer_mode_reg = TRANSFER_GO | BRAIND;
...@@ -244,31 +256,35 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled) ...@@ -244,31 +256,35 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
nsp_index_write(base, TRANSFERMODE, transfer_mode_reg); 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 * Initialize Ninja hardware
*/ */
static int nsphw_init(nsp_hw_data *data) static int nsphw_init(nsp_hw_data *data)
{ {
unsigned int base = data->BaseAddress; 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->CurrentSC = NULL;
data->FifoCount = 0; data->FifoCount = 0;
data->TransferMode = MODE_IO8; data->TransferMode = MODE_IO8;
/* setup sync data */ nsphw_init_sync(data);
for ( i = 0; i < N_TARGET; i++ ) {
for ( j = 0; j < N_LUN; j++ ) {
data->Sync[i][j] = tmp_sync;
}
}
/* block all interrupts */ /* block all interrupts */
nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK); nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
...@@ -321,10 +337,10 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, ...@@ -321,10 +337,10 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
unsigned int host_id = SCpnt->host->this_id; unsigned int host_id = SCpnt->host->this_id;
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
unsigned char target = SCpnt->target; unsigned char target = SCpnt->target;
int wait_count; int time_out;
unsigned char phase, arbit; unsigned char phase, arbit;
//DEBUG(0, __FUNCTION__ "()in\n"); //DEBUG(0, __func__ "()in\n");
phase = nsp_index_read(base, SCSIBUSMON); phase = nsp_index_read(base, SCSIBUSMON);
if(phase != BUSMON_BUS_FREE) { if(phase != BUSMON_BUS_FREE) {
...@@ -337,14 +353,14 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, ...@@ -337,14 +353,14 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
SCpnt->SCp.phase = PH_ARBSTART; SCpnt->SCp.phase = PH_ARBSTART;
nsp_index_write(base, SETARBIT, ARBIT_GO); nsp_index_write(base, SETARBIT, ARBIT_GO);
wait_count = jiffies + 10 * HZ; time_out = 1000;
do { do {
/* XXX: what a stupid chip! */ /* XXX: what a stupid chip! */
arbit = nsp_index_read(base, ARBITSTATUS); arbit = nsp_index_read(base, ARBITSTATUS);
//DEBUG(0, " arbit=%d, wait_count=%d\n", arbit, wait_count); //DEBUG(0, " arbit=%d, wait_count=%d\n", arbit, wait_count);
udelay(1); /* hold 1.2us */ udelay(1); /* hold 1.2us */
} while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 && } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
time_before(jiffies, wait_count)); (time_out-- != 0));
if((arbit & ARBIT_WIN) == 0) { if((arbit & ARBIT_WIN) == 0) {
//DEBUG(0, " arbit fail\n"); //DEBUG(0, " arbit fail\n");
...@@ -356,13 +372,13 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, ...@@ -356,13 +372,13 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
//DEBUG(0, " assert SEL line\n"); //DEBUG(0, " assert SEL line\n");
SCpnt->SCp.phase = PH_SELSTART; SCpnt->SCp.phase = PH_SELSTART;
udelay(3); udelay(3);
nsp_index_write(base, SCSIDATALATCH, (1 << host_id) | (1 << target)); nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN); nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
udelay(3); udelay(3);
nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN); nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR); nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
udelay(3); 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 */ /* check selection timeout */
nsp_start_timer(SCpnt, data, 1000/51); nsp_start_timer(SCpnt, data, 1000/51);
...@@ -399,23 +415,21 @@ static struct nsp_sync_table nsp_sync_table_20M[] = { ...@@ -399,23 +415,21 @@ static struct nsp_sync_table nsp_sync_table_20M[] = {
static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data) static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{ {
unsigned char target = SCpnt->target; unsigned char target = SCpnt->target;
unsigned char lun = SCpnt->lun; // unsigned char lun = SCpnt->lun;
sync_data *sync = &(data->Sync[target][lun]); sync_data *sync = &(data->Sync[target]);
struct nsp_sync_table *sync_table; struct nsp_sync_table *sync_table;
unsigned int period, offset; unsigned int period, offset;
int i; int i;
DEBUG(0, __FUNCTION__ "()\n"); DEBUG(0, "%s()\n", __FUNCTION__);
/**!**/
period = sync->SyncPeriod; period = sync->SyncPeriod;
offset = sync->SyncOffset; offset = sync->SyncOffset;
DEBUG(0, " period=0x%x, offset=0x%x\n", period, offset); 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]; sync_table = &nsp_sync_table_20M[0];
} else { } else {
sync_table = &nsp_sync_table_40M[0]; sync_table = &nsp_sync_table_40M[0];
...@@ -438,7 +452,6 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -438,7 +452,6 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
sync->SyncOffset = 0; sync->SyncOffset = 0;
sync->SyncRegister = 0; sync->SyncRegister = 0;
sync->AckWidth = 0; sync->AckWidth = 0;
sync->SyncNegotiation = SYNC_OK;
return FALSE; return FALSE;
} }
...@@ -446,7 +459,6 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -446,7 +459,6 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) | sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
(offset & SYNCREG_OFFSET_MASK); (offset & SYNCREG_OFFSET_MASK);
sync->AckWidth = sync_table->ack_width; 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); 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) ...@@ -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; 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; data->TimerCount = time;
nsp_index_write(base, 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) ...@@ -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 int base = SCpnt->host->io_port;
unsigned char reg; 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 { do {
reg = nsp_index_read(base, SCSIBUSMON); reg = nsp_index_read(base, SCSIBUSMON);
if (reg == 0xff) { if (reg == 0xff) {
break; break;
} }
} while ((i = time_before(jiffies, count)) && (reg & mask) != 0); } while ((time_out-- != 0) && (reg & mask) != 0);
if (!i) { if (time_out == 0) {
printk(KERN_DEBUG __FUNCTION__ " %s signal off timeut\n", str); printk(KERN_DEBUG "%s: %s signal off timeut\n", __FUNCTION__, str);
} }
return 0; return 0;
...@@ -501,12 +513,12 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt, ...@@ -501,12 +513,12 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
unsigned char mask) unsigned char mask)
{ {
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
int wait_count; int time_out;
unsigned char phase, i_src; 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 { do {
phase = nsp_index_read(base, SCSIBUSMON); phase = nsp_index_read(base, SCSIBUSMON);
if (phase == 0xff) { if (phase == 0xff) {
...@@ -522,9 +534,9 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt, ...@@ -522,9 +534,9 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
//DEBUG(0, " ret 1 phase=0x%x\n", phase); //DEBUG(0, " ret 1 phase=0x%x\n", phase);
return 1; 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; return -1;
} }
...@@ -539,7 +551,7 @@ static int nsp_xfer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int phase) ...@@ -539,7 +551,7 @@ static int nsp_xfer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int phase)
int ptr; int ptr;
int ret; int ret;
//DEBUG(0, __FUNCTION__ "()\n"); //DEBUG(0, __func__ "()\n");
for (ptr = 0; len > 0; len --, ptr ++) { for (ptr = 0; len > 0; len --, ptr ++) {
ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ); ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
...@@ -574,7 +586,7 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -574,7 +586,7 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{ {
unsigned int count; unsigned int count;
//DEBUG(0, __FUNCTION__ "()\n"); //DEBUG(0, __func__ "()\n");
if (SCpnt->SCp.have_data_in != IO_IN) { if (SCpnt->SCp.have_data_in != IO_IN) {
return 0; return 0;
...@@ -590,11 +602,11 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -590,11 +602,11 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
* XXX: NSP_QUIRK * XXX: NSP_QUIRK
* data phase skip only occures in case of SCSI_LOW_READ * data phase skip only occures in case of SCSI_LOW_READ
*/ */
DEBUG(0, " use bypass quirk\n");
SCpnt->SCp.phase = PH_DATA; SCpnt->SCp.phase = PH_DATA;
nsp_pio_read(SCpnt, data); nsp_pio_read(SCpnt, data);
nsp_setup_fifo(data, FALSE); nsp_setup_fifo(data, FALSE);
DEBUG(0, " use bypass quirk\n");
return 0; return 0;
} }
...@@ -606,7 +618,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -606,7 +618,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
unsigned char reg; unsigned char reg;
//DEBUG(0, __FUNCTION__ "()\n"); //DEBUG(0, __func__ "()\n");
nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>"); nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
...@@ -625,17 +637,18 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt) ...@@ -625,17 +637,18 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
{ {
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
unsigned int count; 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); l = nsp_index_read(base, TRANSFERCOUNT);
m = (unsigned int)nsp_read(base, DATAREG); m = nsp_index_read(base, TRANSFERCOUNT);
h = (unsigned int)nsp_read(base, DATAREG); h = nsp_index_read(base, TRANSFERCOUNT);
dummy = nsp_index_read(base, TRANSFERCOUNT);
count = (h << 16) | (m << 8) | (l << 0); count = (h << 16) | (m << 8) | (l << 0);
//DEBUG(0, __FUNCTION__ "() =0x%x\n", count); //DEBUG(0, __func__ "() =0x%x\n", count);
return count; return count;
} }
...@@ -649,25 +662,27 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt) ...@@ -649,25 +662,27 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
*/ */
static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data) static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{ {
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
int time_out, i; unsigned long mmio_base = SCpnt->host->base;
long time_out;
int ocount, res; int ocount, res;
unsigned char stat, fifo_stat; unsigned char stat, fifo_stat;
ocount = data->FifoCount; 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 ) ) { (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
stat = nsp_index_read(base, SCSIBUSMON); stat = nsp_index_read(base, SCSIBUSMON);
stat &= BUSMON_PHASE_MASK; 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); //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 (res == 0) { /* if some data avilable ? */
if (stat == BUSPHASE_DATA_IN) { /* phase changed? */ if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
...@@ -695,9 +710,15 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -695,9 +710,15 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
case MODE_IO8: case MODE_IO8:
nsp_fifo8_read (base, SCpnt->SCp.ptr, res ); nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
break; break;
case MODE_MEM32:
res &= ~(BIT(1)|BIT(0)); /* align 4 */
nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
break;
default: default:
DEBUG(0, "unknown read mode\n"); DEBUG(0, "unknown read mode\n");
break; return;
} }
RESID -= res; RESID -= res;
...@@ -712,17 +733,19 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -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); //DEBUG(0, " scatterlist next timeout=%d\n", time_out);
SCpnt->SCp.buffers_residual--; SCpnt->SCp.buffers_residual--;
SCpnt->SCp.buffer++; SCpnt->SCp.buffer++;
SCpnt->SCp.ptr = SCpnt->SCp.buffer->address; SCpnt->SCp.ptr = BUFFER_ADDR;
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; 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; data->FifoCount = ocount;
if (!i) { if (time_out == 0) {
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); 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); DEBUG(0, " read ocount=0x%x\n", ocount);
} }
...@@ -733,22 +756,32 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -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) static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{ {
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
int time_out, i; unsigned long mmio_base = SCpnt->host->base;
unsigned int ocount, res; int time_out;
int ocount, res;
unsigned char stat; unsigned char stat;
ocount = data->FifoCount; 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)) { (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
stat = nsp_index_read(base, SCSIBUSMON); stat = nsp_index_read(base, SCSIBUSMON);
stat &= BUSMON_PHASE_MASK; stat &= BUSMON_PHASE_MASK;
if (stat != BUSPHASE_DATA_OUT) { 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; break;
} }
...@@ -769,6 +802,12 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -769,6 +802,12 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
case MODE_IO8: case MODE_IO8:
nsp_fifo8_write (base, SCpnt->SCp.ptr, res ); nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
break; break;
case MODE_MEM32:
res &= ~(BIT(1)|BIT(0)); /* align 4 */
nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
break;
default: default:
DEBUG(0, "unknown write mode\n"); DEBUG(0, "unknown write mode\n");
break; break;
...@@ -785,19 +824,18 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -785,19 +824,18 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
//DEBUG(0, " scatterlist next\n"); //DEBUG(0, " scatterlist next\n");
SCpnt->SCp.buffers_residual--; SCpnt->SCp.buffers_residual--;
SCpnt->SCp.buffer++; SCpnt->SCp.buffer++;
SCpnt->SCp.ptr = SCpnt->SCp.buffer->address; SCpnt->SCp.ptr = BUFFER_ADDR;
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
time_out = 1000;
} }
time_out = jiffies + 10 * HZ;
} }
data->FifoCount = ocount; data->FifoCount = ocount;
if (!i) { if (time_out == 0) {
printk(KERN_DEBUG __FUNCTION__ "() pio write timeout resid=%d\n", RESID); 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 #undef RFIFO_CRIT
...@@ -810,20 +848,25 @@ static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data) ...@@ -810,20 +848,25 @@ static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{ {
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
unsigned char target = SCpnt->target; unsigned char target = SCpnt->target;
unsigned char lun = SCpnt->lun; // unsigned char lun = SCpnt->lun;
sync_data *sync = &(data->Sync[target][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 */ /* setup synch transfer registers */
nsp_index_write(base, SYNCREG, sync->SyncRegister); nsp_index_write(base, SYNCREG, sync->SyncRegister);
nsp_index_write(base, ACKWIDTH, sync->AckWidth); nsp_index_write(base, ACKWIDTH, sync->AckWidth);
if (RESID % 4 != 0 || if (SCpnt->use_sg == 0 ||
RESID <= 256 ) { RESID % 4 != 0 ||
RESID <= PAGE_SIZE ) {
data->TransferMode = MODE_IO8; 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; data->TransferMode = MODE_IO32;
} else {
data->TransferMode = MODE_IO8;
} }
/* setup pdma fifo */ /* setup pdma fifo */
...@@ -848,24 +891,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -848,24 +891,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
unsigned int base; unsigned int base;
unsigned char i_src, irq_phase, phase; unsigned char i_src, irq_phase, phase;
Scsi_Cmnd *tmpSC; Scsi_Cmnd *tmpSC;
int len;
unsigned char target, lun; unsigned char target, lun;
unsigned int *sync_neg; unsigned int *sync_neg;
int i, tmp; 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); //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; base = data->BaseAddress;
//DEBUG(0, " base=0x%x\n", base); //DEBUG(0, " base=0x%x\n", base);
...@@ -874,13 +906,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -874,13 +906,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
*/ */
nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE); nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
i_src = nsp_read(base, IRQSTATUS); 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); nsp_write(base, IRQCONTROL, 0);
//DEBUG(0, " no irq\n"); //DEBUG(0, " no irq/shared irq\n");
return; return;
} }
//DEBUG(0, " i_src=0x%x\n", i_src);
/* XXX: IMPORTANT /* XXX: IMPORTANT
* Do not read an irq_phase register if no scsi phase interrupt. * 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) ...@@ -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); nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
if (data->CurrentSC == NULL) { 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; return;
} else { } else {
tmpSC = data->CurrentSC; tmpSC = data->CurrentSC;
target = tmpSC->target; target = tmpSC->target;
lun = tmpSC->lun; 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) ...@@ -930,10 +962,12 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
*/ */
if ((i_src & IRQSTATUS_SCSI) != 0) { if ((i_src & IRQSTATUS_SCSI) != 0) {
if ((irq_phase & SCSI_RESET_IRQ) != 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; *sync_neg = SYNC_NOT_YET;
data->CurrentSC = NULL; 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); tmpSC->scsi_done(tmpSC);
return; return;
} }
...@@ -955,7 +989,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -955,7 +989,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
switch(tmpSC->SCp.phase) { switch(tmpSC->SCp.phase) {
case PH_SELSTART: case PH_SELSTART:
*sync_neg = SYNC_NOT_YET; //*sync_neg = SYNC_NOT_YET;
if ((phase & BUSMON_BSY) == 0) { if ((phase & BUSMON_BSY) == 0) {
//DEBUG(0, " selection count=%d\n", data->SelectionTimeOut); //DEBUG(0, " selection count=%d\n", data->SelectionTimeOut);
if (data->SelectionTimeOut >= NSP_SELTIMEOUT) { if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
...@@ -987,7 +1021,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -987,7 +1021,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
case PH_RESELECT: case PH_RESELECT:
//DEBUG(0, " phase reselect\n"); //DEBUG(0, " phase reselect\n");
*sync_neg = SYNC_NOT_YET; //*sync_neg = SYNC_NOT_YET;
if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) { if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
data->CurrentSC = NULL; data->CurrentSC = NULL;
...@@ -1009,16 +1043,18 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1009,16 +1043,18 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
//DEBUG(0, " start scsi seq\n"); //DEBUG(0, " start scsi seq\n");
/* normal disconnect */ /* normal disconnect */
if ((irq_phase & LATCHED_BUS_FREE) != 0) { if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
//DEBUG(0, " normal disconnect i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase); (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 */ 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; data->CurrentSC = NULL;
tmpSC->result = (DID_OK << 16) | tmpSC->result = (DID_OK << 16) |
(tmpSC->SCp.Message << 8) | ((tmpSC->SCp.Message & 0xff) << 8) |
(tmpSC->SCp.Status << 0); ((tmpSC->SCp.Status & 0xff) << 0);
DEBUG(0, " command complete result=0x%x\n", tmpSC->result); DEBUG(0, " command complete result=0x%x\n", tmpSC->result);
tmpSC->scsi_done(tmpSC); tmpSC->scsi_done(tmpSC);
return; return;
} }
...@@ -1028,7 +1064,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1028,7 +1064,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
/* check unexpected bus free state */ /* check unexpected bus free state */
if (phase == 0) { 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; *sync_neg = SYNC_NOT_YET;
data->CurrentSC = NULL; data->CurrentSC = NULL;
...@@ -1050,9 +1086,10 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1050,9 +1086,10 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
nsp_nexus(tmpSC, data); nsp_nexus(tmpSC, data);
/* write scsi command */ /* write scsi command */
DEBUG(0, " cmd_len=%d\n", tmpSC->cmd_len);
nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER); nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
for (len = 0; len < COMMAND_SIZE(tmpSC->cmnd[0]); len++) { for (i = 0; i < tmpSC->cmd_len; i++) {
nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[len]); nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
} }
nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO); nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
break; break;
...@@ -1084,7 +1121,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1084,7 +1121,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC->SCp.phase = PH_STATUS; tmpSC->SCp.phase = PH_STATUS;
tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK); 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; break;
...@@ -1096,26 +1133,24 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1096,26 +1133,24 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC->SCp.phase = PH_MSG_OUT; tmpSC->SCp.phase = PH_MSG_OUT;
data->MsgLen = len = 0; data->MsgLen = i = 0;
if (*sync_neg == SYNC_NOT_YET) { data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
data->Sync[target][lun].SyncPeriod = 0;
data->Sync[target][lun].SyncOffset = 0;
nsp_msg(tmpSC, data);
data->MsgBuffer[len] = IDENTIFY(TRUE, lun); len++; if (*sync_neg == SYNC_NOT_YET) {
/* data->Sync[target].SyncPeriod = 0;
data->MsgBuffer[len] = MSG_EXTENDED; len++; data->Sync[target].SyncOffset = 0;
data->MsgBuffer[len] = 3; len++;
data->MsgBuffer[len] = MSG_EXT_SDTR; len++; /**/
data->MsgBuffer[len] = 0x0c; len++; data->MsgBuffer[i] = MSG_EXTENDED; i++;
data->MsgBuffer[len] = 15; len++; data->MsgBuffer[i] = 3; i++;
*/ data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
} data->MsgBuffer[i] = 0x0c; i++;
if (len == 0) { data->MsgBuffer[i] = 15; i++;
data->MsgBuffer[len] = MSG_NO_OPERATION; len++; /**/
} }
data->MsgLen = len; data->MsgLen = i;
nsp_msg(tmpSC, data);
show_message(data); show_message(data);
nsp_message_out(tmpSC, data); nsp_message_out(tmpSC, data);
break; break;
...@@ -1130,16 +1165,26 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1130,16 +1165,26 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC->SCp.phase = PH_MSG_IN; tmpSC->SCp.phase = PH_MSG_IN;
nsp_message_in(tmpSC, data); nsp_message_in(tmpSC, data);
/* /**/
if (data->MsgLen >= 5 && if (*sync_neg == SYNC_NOT_YET) {
data->MsgBuffer[0] == MSG_EXTENDED && //printk("%d,%d\n",target,lun);
data->MsgBuffer[1] == 3 &&
data->MsgBuffer[2] == MSG_EXT_SDTR ) { if (data->MsgLen >= 5 &&
data->Sync[target][lun].SyncPeriod = data->MsgBuffer[3]; data->MsgBuffer[0] == MSG_EXTENDED &&
data->Sync[target][lun].SyncOffset = data->MsgBuffer[4]; 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); nsp_msg(tmpSC, data);
} }
*/ /**/
/* search last messeage byte */ /* search last messeage byte */
tmp = -1; tmp = -1;
...@@ -1163,7 +1208,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1163,7 +1208,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
break; break;
} }
//DEBUG(0, __FUNCTION__ "() out\n"); //DEBUG(0, __func__ "() out\n");
return; return;
timer_out: timer_out:
...@@ -1183,41 +1228,52 @@ static int nsp_detect(Scsi_Host_Template *sht) ...@@ -1183,41 +1228,52 @@ static int nsp_detect(Scsi_Host_Template *sht)
struct Scsi_Host *host; /* registered host structure */ struct Scsi_Host *host; /* registered host structure */
nsp_hw_data *data = &nsp_data; 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"); request_region(data->BaseAddress, data->NumAddress, "nsp_cs");
host = scsi_register(sht, 0); host = scsi_register(sht, 0);
host->io_port = data->BaseAddress;
host->unique_id = data->BaseAddress; host->unique_id = data->BaseAddress;
host->io_port = data->BaseAddress;
host->n_io_port = data->NumAddress; host->n_io_port = data->NumAddress;
host->irq = data->IrqNumber; 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, DEBUG(0, "%s: end\n", __FUNCTION__);
/* 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, __FUNCTION__ " end\n"); //MOD_INC_USE_COUNT;
return 1; /* detect done. */ return 1; /* detect done. */
} }
/* nsp_cs requires own release handler because its uses dev_id (=data) */
static int nsp_release(struct Scsi_Host *shpnt) 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; return 0;
} }
...@@ -1226,25 +1282,152 @@ static int nsp_release(struct Scsi_Host *shpnt) ...@@ -1226,25 +1282,152 @@ 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)
{ {
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 */ /* 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) 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); nsp_eh_bus_reset(SCpnt);
return SCSI_ABORT_SUCCESS; return SCSI_ABORT_SUCCESS;
...@@ -1255,28 +1438,29 @@ static int nsp_abort(Scsi_Cmnd *SCpnt) ...@@ -1255,28 +1438,29 @@ static int nsp_abort(Scsi_Cmnd *SCpnt)
return FAILED; return FAILED;
}*/ }*/
/*
static int nsp_eh_abort(Scsi_Cmnd *SCpnt) 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 nsp_eh_bus_reset(SCpnt);
}*/
return SUCCESS;
}
/*
static int nsp_eh_device_reset(Scsi_Cmnd *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; return FAILED;
} }*/
static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
{ {
nsp_hw_data *data = &nsp_data;
unsigned int base = SCpnt->host->io_port; unsigned int base = SCpnt->host->io_port;
int i; 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); nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
...@@ -1289,6 +1473,8 @@ static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) ...@@ -1289,6 +1473,8 @@ static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR); nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
nsphw_init_sync(data);
return SUCCESS; return SUCCESS;
} }
...@@ -1296,17 +1482,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt) ...@@ -1296,17 +1482,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
{ {
nsp_hw_data *data = &nsp_data; nsp_hw_data *data = &nsp_data;
DEBUG(0, __FUNCTION__ "\n"); DEBUG(0, "%s\n", __FUNCTION__);
nsphw_init(data); nsphw_init(data);
return nsp_eh_bus_reset(SCpnt); return SUCCESS;
} }
/********************************************************************** /**********************************************************************
PCMCIA functions PCMCIA functions
*********************************************************************/ **********************************************************************/
/*====================================================================*/ /*====================================================================*/
static void cs_error(client_handle_t handle, int func, int ret) static void cs_error(client_handle_t handle, int func, int ret)
...@@ -1331,7 +1517,7 @@ static dev_link_t *nsp_cs_attach(void) ...@@ -1331,7 +1517,7 @@ static dev_link_t *nsp_cs_attach(void)
dev_link_t *link; dev_link_t *link;
int ret, i; int ret, i;
DEBUG(0, __FUNCTION__ "()\n"); DEBUG(0, "%s()\n", __FUNCTION__);
/* Create new SCSI device */ /* Create new SCSI device */
info = kmalloc(sizeof(*info), GFP_KERNEL); info = kmalloc(sizeof(*info), GFP_KERNEL);
...@@ -1359,8 +1545,15 @@ static dev_link_t *nsp_cs_attach(void) ...@@ -1359,8 +1545,15 @@ static dev_link_t *nsp_cs_attach(void)
link->irq.IRQInfo2 |= 1 << irq_list[i]; 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.Handler = &nspintr;
link->irq.Instance = &nsp_data; link->irq.Instance = &nsp_data;
link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
/* General socket configuration */ /* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Attributes = CONF_ENABLE_IRQ;
...@@ -1402,7 +1595,7 @@ static void nsp_cs_detach(dev_link_t *link) ...@@ -1402,7 +1595,7 @@ static void nsp_cs_detach(dev_link_t *link)
{ {
dev_link_t **linkp; dev_link_t **linkp;
DEBUG(0, __FUNCTION__ "(0x%p)\n", link); DEBUG(0, "%s(0x%p)\n", __FUNCTION__, link);
/* Locate device structure */ /* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
...@@ -1414,7 +1607,7 @@ static void nsp_cs_detach(dev_link_t *link) ...@@ -1414,7 +1607,7 @@ static void nsp_cs_detach(dev_link_t *link)
return; return;
} }
del_timer(&link->release); del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) { if (link->state & DEV_CONFIG) {
nsp_cs_release((u_long)link); nsp_cs_release((u_long)link);
if (link->state & DEV_STALE_CONFIG) { if (link->state & DEV_STALE_CONFIG) {
...@@ -1431,6 +1624,7 @@ static void nsp_cs_detach(dev_link_t *link) ...@@ -1431,6 +1624,7 @@ static void nsp_cs_detach(dev_link_t *link)
/* Unlink device structure, free bits */ /* Unlink device structure, free bits */
*linkp = link->next; *linkp = link->next;
kfree(link->priv); kfree(link->priv);
link->priv = NULL;
} /* nsp_cs_detach */ } /* nsp_cs_detach */
...@@ -1452,15 +1646,20 @@ static void nsp_cs_config(dev_link_t *link) ...@@ -1452,15 +1646,20 @@ static void nsp_cs_config(dev_link_t *link)
scsi_info_t *info = link->priv; scsi_info_t *info = link->priv;
tuple_t tuple; tuple_t tuple;
cisparse_t parse; cisparse_t parse;
int i, last_ret, last_fn; int last_ret, last_fn;
u_char tuple_data[64]; u_char tuple_data[64];
config_info_t conf; config_info_t conf;
win_req_t req;
memreq_t map;
cistpl_cftable_entry_t dflt = { 0 };
Scsi_Device *dev; Scsi_Device *dev;
dev_node_t **tail, *node; dev_node_t **tail, *node;
struct Scsi_Host *host; struct Scsi_Host *host;
nsp_hw_data *data = &nsp_data; nsp_hw_data *data = &nsp_data;
DEBUG(0, __FUNCTION__ "() in\n");
DEBUG(0, "%s() in\n", __FUNCTION__);
tuple.DesiredTuple = CISTPL_CONFIG; tuple.DesiredTuple = CISTPL_CONFIG;
tuple.Attributes = 0; tuple.Attributes = 0;
...@@ -1474,7 +1673,6 @@ static void nsp_cs_config(dev_link_t *link) ...@@ -1474,7 +1673,6 @@ static void nsp_cs_config(dev_link_t *link)
link->conf.Present = parse.config.rmask[0]; link->conf.Present = parse.config.rmask[0];
/* Configure card */ /* Configure card */
driver_template.module = &__this_module;
link->state |= DEV_CONFIG; link->state |= DEV_CONFIG;
/* Look up the current Vcc */ /* Look up the current Vcc */
...@@ -1484,44 +1682,130 @@ static void nsp_cs_config(dev_link_t *link) ...@@ -1484,44 +1682,130 @@ static void nsp_cs_config(dev_link_t *link)
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, handle, &tuple); CS_CHECK(GetFirstTuple, handle, &tuple);
while (1) { while (1) {
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
CFG_CHECK(GetTupleData, handle, &tuple); CFG_CHECK(GetTupleData, handle, &tuple);
CFG_CHECK(ParseTuple, handle, &tuple, &parse); CFG_CHECK(ParseTuple, handle, &tuple, &parse);
link->conf.ConfigIndex = parse.cftable_entry.index;
link->io.BasePort1 = parse.cftable_entry.io.win[0].base; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
i = CardServices(RequestIO, handle, &link->io); if (cfg->index == 0) { goto next_entry; }
if (i == CS_SUCCESS) { link->conf.ConfigIndex = cfg->index;
break;
/* 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: 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(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); CS_CHECK(RequestConfiguration, handle, &link->conf);
/* A bad hack... */ if (free_ports) {
release_region(link->io.BasePort1, link->io.NumPorts1); 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 */ /* Set port and IRQ */
data->BaseAddress = link->io.BasePort1; data->BaseAddress = link->io.BasePort1;
data->NumAddress = link->io.NumPorts1; data->NumAddress = link->io.NumPorts1;
data->IrqNumber = link->irq.AssignedIRQ; 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); data->BaseAddress, data->NumAddress, data->IrqNumber);
if(nsphw_init(data) == FALSE) { if(nsphw_init(data) == FALSE) {
goto cs_failed; goto cs_failed;
} }
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_register_host(&driver_template); scsi_register_host(&driver_template);
#else
scsi_register_module(MODULE_SCSI_HA, &driver_template);
#endif
DEBUG(0, "GET_SCSI_INFO\n"); DEBUG(0, "GET_SCSI_INFO\n");
tail = &link->dev; tail = &link->dev;
info->ndev = 0; info->ndev = 0;
for (host = scsi_host_get_next(NULL); host; 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) { if (host->hostt == &driver_template) {
for (dev = host->host_queue; dev != NULL; dev = dev->next) { for (dev = host->host_queue; dev != NULL; dev = dev->next) {
u_long arg[2], id; u_long arg[2], id;
...@@ -1575,6 +1859,12 @@ static void nsp_cs_config(dev_link_t *link) ...@@ -1575,6 +1859,12 @@ static void nsp_cs_config(dev_link_t *link)
printk(", io 0x%04x-0x%04x", link->io.BasePort1, printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1+link->io.NumPorts1-1); 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"); printk("\n");
link->state &= ~DEV_CONFIG_PENDING; link->state &= ~DEV_CONFIG_PENDING;
...@@ -1598,7 +1888,7 @@ static void nsp_cs_release(u_long arg) ...@@ -1598,7 +1888,7 @@ static void nsp_cs_release(u_long arg)
{ {
dev_link_t *link = (dev_link_t *)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 * 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) ...@@ -1612,10 +1902,15 @@ static void nsp_cs_release(u_long arg)
} }
/* Unlink the device chain */ /* Unlink the device chain */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_unregister_host(&driver_template); scsi_unregister_host(&driver_template);
#else
scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
#endif
link->dev = NULL; link->dev = NULL;
if (link->win) { if (link->win) {
iounmap((void *)(nsp_data.MmioAddress));
CardServices(ReleaseWindow, link->win); CardServices(ReleaseWindow, link->win);
} }
CardServices(ReleaseConfiguration, link->handle); CardServices(ReleaseConfiguration, link->handle);
...@@ -1645,14 +1940,15 @@ static void nsp_cs_release(u_long arg) ...@@ -1645,14 +1940,15 @@ static void nsp_cs_release(u_long arg)
the card is still present. the card is still present.
======================================================================*/ ======================================================================*/
static int nsp_cs_event(event_t event, static int nsp_cs_event(event_t event,
int priority, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
scsi_info_t *info = link->priv; 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) { switch (event) {
case CS_EVENT_CARD_REMOVAL: case CS_EVENT_CARD_REMOVAL:
...@@ -1688,20 +1984,21 @@ static int nsp_cs_event(event_t event, ...@@ -1688,20 +1984,21 @@ static int nsp_cs_event(event_t event,
case CS_EVENT_CARD_RESET: case CS_EVENT_CARD_RESET:
DEBUG(0, " event: reset\n"); DEBUG(0, " event: reset\n");
if (link->state & DEV_CONFIG) { if (link->state & DEV_CONFIG) {
Scsi_Cmnd tmp;
CardServices(RequestConfiguration, link->handle, &link->conf); CardServices(RequestConfiguration, link->handle, &link->conf);
tmp.host = info->host;
nsp_eh_host_reset(&tmp);
} }
info->stop = 0; info->stop = 0;
tmp.host = info->host;
nsp_eh_host_reset(&tmp);
nsp_eh_bus_reset(&tmp);
break; break;
default: default:
DEBUG(0, " event: unknown\n"); DEBUG(0, " event: unknown\n");
break; break;
} }
DEBUG(0, __FUNCTION__ " end\n"); DEBUG(0, "%s end\n", __FUNCTION__);
return 0; return 0;
} /* nsp_cs_event */ } /* nsp_cs_event */
...@@ -1712,7 +2009,7 @@ static int __init nsp_cs_init(void) ...@@ -1712,7 +2009,7 @@ static int __init nsp_cs_init(void)
{ {
servinfo_t serv; servinfo_t serv;
DEBUG(0, __FUNCTION__ "() in\n"); DEBUG(0, "%s() in\n", __FUNCTION__);
DEBUG(0, "%s\n", version); DEBUG(0, "%s\n", version);
CardServices(GetCardServicesInfo, &serv); CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) { if (serv.Revision != CS_RELEASE_CODE) {
...@@ -1722,14 +2019,14 @@ static int __init nsp_cs_init(void) ...@@ -1722,14 +2019,14 @@ static int __init nsp_cs_init(void)
} }
register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach); register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
DEBUG(0, __FUNCTION__ "() out\n"); DEBUG(0, "%s() out\n", __FUNCTION__);
return 0; return 0;
} }
static void __exit nsp_cs_cleanup(void) static void __exit nsp_cs_cleanup(void)
{ {
DEBUG(0, __FUNCTION__ "() unloading\n"); DEBUG(0, "%s() unloading\n", __FUNCTION__);
unregister_pcmcia_driver(&dev_info); unregister_pcmcia_driver(&dev_info);
while (dev_list != NULL) { while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG) { if (dev_list->state & DEV_CONFIG) {
...@@ -1739,8 +2036,8 @@ static void __exit nsp_cs_cleanup(void) ...@@ -1739,8 +2036,8 @@ static void __exit nsp_cs_cleanup(void)
} }
} }
module_init(nsp_cs_init); module_init(nsp_cs_init)
module_exit(nsp_cs_cleanup); module_exit(nsp_cs_cleanup)
/* /*
* *
......
...@@ -10,13 +10,13 @@ ...@@ -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__ #ifndef __nsp_cs__
#define __nsp_cs__ #define __nsp_cs__
/* for debugging */ /* for debugging */
/*#define PCMCIA_DEBUG 9*/ //#define PCMCIA_DEBUG 9
/* /*
#define static #define static
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
* Some useful macros... * Some useful macros...
*/ */
#define Number(arr) ((int) (sizeof(arr) / sizeof(arr[0]))) #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)) #define MIN(a,b) ((a) > (b) ? (b) : (a))
/* SCSI initiator must be 7 */ /* SCSI initiator must be ID 7 */
#define SCSI_INITIATOR_ID 7 #define NSP_INITIATOR_ID 7
#define NSP_SELTIMEOUT 200 #define NSP_SELTIMEOUT 200
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
#define CLOCKDIV 0x11 #define CLOCKDIV 0x11
# define CLOCK_40M 0x02 # define CLOCK_40M 0x02
# define CLOCK_20M 0x01 # define CLOCK_20M 0x01
# define FAST_20 BIT(2)
#define TERMPWRCTRL 0x13 #define TERMPWRCTRL 0x13
# define POWER_ON BIT(0) # define POWER_ON BIT(0)
...@@ -133,6 +134,9 @@ ...@@ -133,6 +134,9 @@
# define REQ_COUNTER_CLEAR BIT(2) # define REQ_COUNTER_CLEAR BIT(2)
# define HOST_COUNTER_CLEAR BIT(3) # define HOST_COUNTER_CLEAR BIT(3)
# define READ_SOURCE 0x30 # define READ_SOURCE 0x30
# define ACK_COUNTER (0)
# define REQ_COUNTER (BIT(4))
# define HOST_COUNTER (BIT(5))
#define TRANSFERCOUNT 0x1E /* R */ #define TRANSFERCOUNT 0x1E /* R */
...@@ -222,11 +226,14 @@ typedef struct _sync_data { ...@@ -222,11 +226,14 @@ typedef struct _sync_data {
unsigned char AckWidth; unsigned char AckWidth;
} sync_data; } sync_data;
typedef struct _nsp_data { typedef struct _nsp_hw_data {
unsigned int BaseAddress; unsigned int BaseAddress;
unsigned int NumAddress; unsigned int NumAddress;
unsigned int IrqNumber; unsigned int IrqNumber;
unsigned long MmioAddress;
#define NSP_MMIO_OFFSET 0x0800
unsigned char ScsiClockDiv; unsigned char ScsiClockDiv;
unsigned char TransferMode; unsigned char TransferMode;
...@@ -238,9 +245,9 @@ typedef struct _nsp_data { ...@@ -238,9 +245,9 @@ typedef struct _nsp_data {
int FifoCount; int FifoCount;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
int Residual; int Residual;
#define RESID data->Residual #define RESID (data->Residual)
#else #else
#define RESID SCpnt->resid #define RESID (SCpnt->resid)
#endif #endif
#define MSGBUF_SIZE 20 #define MSGBUF_SIZE 20
...@@ -248,10 +255,20 @@ typedef struct _nsp_data { ...@@ -248,10 +255,20 @@ typedef struct _nsp_data {
int MsgLen; int MsgLen;
#define N_TARGET 8 #define N_TARGET 8
#define N_LUN 8 sync_data Sync[N_TARGET];
sync_data Sync[N_TARGET][N_LUN];
char nspinfo[110]; /* description */
spinlock_t Lock;
} nsp_hw_data; } 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 void nsp_cs_release(u_long arg);
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);
...@@ -263,14 +280,16 @@ static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time); ...@@ -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_detect(Scsi_Host_Template * );
static int nsp_release(struct Scsi_Host *shpnt); 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_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
static int nsp_abort(Scsi_Cmnd *); static int nsp_abort(Scsi_Cmnd *);
static int nsp_reset(Scsi_Cmnd *, unsigned int); static int nsp_reset(Scsi_Cmnd *, unsigned int);
static int nsp_eh_abort(Scsi_Cmnd * SCpnt); /*static int nsp_eh_abort(Scsi_Cmnd * SCpnt);*/
static int nsp_eh_device_reset(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_bus_reset(Scsi_Cmnd *SCpnt);
static int nsp_eh_host_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); ...@@ -294,17 +313,19 @@ static void show_message(nsp_hw_data *data);
* SCSI phase * SCSI phase
*/ */
enum _scsi_phase { enum _scsi_phase {
PH_UNDETERMINED, PH_UNDETERMINED ,
PH_ARBSTART, PH_ARBSTART ,
PH_SELSTART, PH_SELSTART ,
PH_SELECTED, PH_SELECTED ,
PH_COMMAND, PH_COMMAND ,
PH_DATA, PH_DATA ,
PH_STATUS, PH_STATUS ,
PH_MSG_IN, PH_MSG_IN ,
PH_MSG_OUT, PH_MSG_OUT ,
PH_DISCONNECT, PH_DISCONNECT ,
PH_RESELECT PH_RESELECT ,
PH_ABORT ,
PH_RESET
}; };
enum _data_in_out { enum _data_in_out {
...@@ -313,11 +334,19 @@ enum _data_in_out { ...@@ -313,11 +334,19 @@ enum _data_in_out {
IO_OUT IO_OUT
}; };
enum _burst_mode {
BURST_IO8 = 0,
BURST_IO32,
BURST_MEM32
};
/* SCSI messaage */ /* SCSI messaage */
#define MSG_COMMAND_COMPLETE 0x00 #define MSG_COMMAND_COMPLETE 0x00
#define MSG_EXTENDED 0x01 #define MSG_EXTENDED 0x01
#define MSG_ABORT 0x06
#define MSG_NO_OPERATION 0x08 #define MSG_NO_OPERATION 0x08
#define MSG_BUS_DEVICE_RESET 0x0c
#define MSG_EXT_SDTR 0x01 #define MSG_EXT_SDTR 0x01
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
the GNU General Public License. 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 * Show the command data of a command
...@@ -87,14 +87,21 @@ static void print_opcodek(unsigned char opcode) ...@@ -87,14 +87,21 @@ static void print_opcodek(unsigned char opcode)
static void print_commandk (unsigned char *command) static void print_commandk (unsigned char *command)
{ {
int i,s; int i, s;
printk(KERN_DEBUG); printk(KERN_DEBUG);
print_opcodek(command[0]); print_opcodek(command[0]);
/*printk(KERN_DEBUG __FUNCTION__ " ");*/ /*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]); printk("%02x ", command[i]);
} }
switch (COMMAND_SIZE(command[0])) {
switch (s) {
case 6: case 6:
printk("LBA=%d len=%d", printk("LBA=%d len=%d",
(((unsigned int)command[1] & 0x0f) << 16) | (((unsigned int)command[1] & 0x0f) << 16) |
......
...@@ -7,7 +7,7 @@ ...@@ -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__ #ifndef __NSP_IO_H__
#define __NSP_IO_H__ #define __NSP_IO_H__
...@@ -76,7 +76,7 @@ static inline void nsp_fifo8_read(unsigned int base, ...@@ -76,7 +76,7 @@ static inline void nsp_fifo8_read(unsigned int base,
void *buf, void *buf,
unsigned long count) 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); nsp_multi_read_1(base, FIFODATA, buf, count);
} }
...@@ -172,5 +172,103 @@ static inline void nsp_fifo32_write(unsigned int base, ...@@ -172,5 +172,103 @@ static inline void nsp_fifo32_write(unsigned int base,
nsp_multi_write_4(base, FIFODATA, buf, count); 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 #endif
/* end */ /* end */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
the GNU General Public License. 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) 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) ...@@ -64,7 +64,7 @@ static void nsp_message_out(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
DEBUG(0, " msgout loop\n"); DEBUG(0, " msgout loop\n");
do { do {
if (nsp_xfer(SCpnt, data, BUSPHASE_MESSAGE_OUT)) { 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 */ /* 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