patch-pre2.0.12 linux/drivers/scsi/qlogicisp.c
Next file: linux/drivers/scsi/qlogicisp.h
Previous file: linux/drivers/scsi/hosts.c
Back to the patch index
Back to the overall index
- Lines: 768
- Date:
Tue Jun 4 06:06:38 1996
- Orig file:
pre2.0.11/linux/drivers/scsi/qlogicisp.c
- Orig date:
Tue May 21 19:52:36 1996
diff -u --recursive --new-file pre2.0.11/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
@@ -51,6 +51,7 @@
#include <unistd.h>
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/delay.h>
#include "sd.h"
#include "hosts.h"
@@ -80,6 +81,8 @@
#define DEBUG_ISP1020_INT 0
#define DEBUG_ISP1020_SETUP 0
+#define DEFAULT_LOOP_COUNT 1000000
+
/* End Configuration section *************************************************/
#include <linux/module.h>
@@ -106,6 +109,9 @@
#define ISP1020_REV_ID 1
+#define MAX_TARGETS 16
+#define MAX_LUNS 8
+
/* host configuration and control registers */
#define HOST_HCCR 0xc0 /* host command and control */
@@ -113,7 +119,7 @@
#define PCI_ID_LOW 0x00 /* vendor id */
#define PCI_ID_HIGH 0x02 /* device id */
#define ISP_CFG0 0x04 /* configuration register #0 */
-#define ISP_CFG1 0x08 /* configuration register #1 */
+#define ISP_CFG1 0x06 /* configuration register #1 */
#define PCI_INTF_CTL 0x08 /* pci interface control */
#define PCI_INTF_STS 0x0a /* pci interface status */
#define PCI_SEMAPHORE 0x0c /* pci semaphore */
@@ -138,7 +144,7 @@
/* async event status codes */
#define ASYNC_SCSI_BUS_RESET 0x8001
#define SYSTEM_ERROR 0x8002
-#define REQUEST_TRANSFER ERROR 0x8003
+#define REQUEST_TRANSFER_ERROR 0x8003
#define RESPONSE_TRANSFER_ERROR 0x8004
#define REQUEST_QUEUE_WAKEUP 0x8005
#define EXECUTION_TIMEOUT_RESET 0x8006
@@ -164,13 +170,13 @@
#define EFLAG_BAD_PAYLOAD 8
struct dataseg {
- caddr_t d_base;
- u_long d_count;
+ u_int d_base;
+ u_int d_count;
};
struct Command_Entry {
struct Entry_header hdr;
- caddr_t handle;
+ u_int handle;
u_char target_lun;
u_char target_id;
u_short cdb_length;
@@ -196,7 +202,7 @@
struct Ext_Command_Entry {
struct Entry_header hdr;
- caddr_t handle;
+ u_int handle;
u_char target_lun;
u_char target_id;
u_short cdb_length;
@@ -209,7 +215,7 @@
struct Continuation_Entry {
struct Entry_header hdr;
- u_long reserved;
+ u_int reserved;
struct dataseg dataseg0;
struct dataseg dataseg1;
struct dataseg dataseg2;
@@ -221,7 +227,7 @@
struct Marker_Entry {
struct Entry_header hdr;
- caddr_t reserved;
+ u_int reserved;
u_char target_lun;
u_char target_id;
u_char modifier;
@@ -236,14 +242,14 @@
struct Status_Entry {
struct Entry_header hdr;
- caddr_t handle;
+ u_int handle;
u_short scsi_status;
u_short completion_status;
u_short state_flags;
u_short status_flags;
u_short time;
u_short req_sense_len;
- u_long residual;
+ u_int residual;
u_char rsvd[8];
u_char req_sense_data[32];
};
@@ -290,6 +296,11 @@
#define STF_TIMEOUT 0x0040
#define STF_NEGOTIATION 0x0080
+/* interface control commands */
+#define ISP_RESET 0x0001
+#define ISP_EN_INT 0x0002
+#define ISP_EN_RISC 0x0004
+
/* host control commands */
#define HCCR_NOP 0x0000
#define HCCR_RESET 0x1000
@@ -300,9 +311,11 @@
#define HCCR_CLEAR_HOST_INTR 0x6000
#define HCCR_CLEAR_RISC_INTR 0x7000
#define HCCR_BP_ENABLE 0x8000
-#define HCCR_BIOS_ENABLE 0x9000
+#define HCCR_BIOS_DISABLE 0x9000
#define HCCR_TEST_MODE 0xf000
+#define RISC_BUSY 0x0004
+
/* mailbox commands */
#define MBOX_NO_OP 0x0000
#define MBOX_LOAD_RAM 0x0001
@@ -467,6 +480,7 @@
u_short synchronous_period;
u_short synchronous_offset;
u_short device_enable;
+ u_short reserved; /* pad */
};
#define REQ_QUEUE_LEN 32
@@ -474,9 +488,9 @@
#define QUEUE_ENTRY_LEN 64
struct isp1020_hostdata {
+ u_int io_base;
u_char irq;
u_char bus;
- u_long io_base;
u_char revision;
u_char device_fn;
u_short res_queue_in_ptr;
@@ -484,12 +498,12 @@
u_short req_queue_in_ptr;
u_short req_queue_out_ptr;
struct host_param host_param;
- struct dev_param dev_param[16];
+ struct dev_param dev_param[MAX_TARGETS];
char res_queue[RES_QUEUE_LEN][QUEUE_ENTRY_LEN];
char req_queue[REQ_QUEUE_LEN][QUEUE_ENTRY_LEN];
};
-struct isp1020_hostdata *irq2host[16];
+struct isp1020_hostdata *irq2host[NR_IRQS];
void isp1020_enable_irqs(struct isp1020_hostdata *);
void isp1020_disable_irqs(struct isp1020_hostdata *);
@@ -505,8 +519,12 @@
void isp1020_print_scsi_cmd(Scsi_Cmnd *);
void isp1020_scsi_done(Scsi_Cmnd *);
int isp1020_return_status(struct Status_Entry *);
-void isp1020_intr_handler(int, struct pt_regs *);
+void isp1020_intr_handler(int, void *, struct pt_regs *);
+struct proc_dir_entry proc_scsi_isp1020 = {
+ PROC_SCSI_QLOGICISP, 7, "isp1020",
+ S_IFDIR | S_IRUGO | S_IXUGO, 2
+};
int isp1020_detect(Scsi_Host_Template *tmpt)
{
@@ -518,6 +536,8 @@
ENTER("isp1020_detect");
+ tmpt->proc_dir = &proc_scsi_isp1020;
+
if (pcibios_present() == 0) {
printk("qlogicisp : PCI bios not present\n");
return 0;
@@ -549,7 +569,7 @@
scsihost->this_id = hostdata->host_param.initiator_scsi_id;
- if (request_irq(hostdata->irq, isp1020_intr_handler, 0,
+ if (request_irq(hostdata->irq, isp1020_intr_handler, SA_INTERRUPT,
"qlogicisp", NULL)) {
printk("qlogicisp : interrupt %d already in use\n", hostdata->irq);
scsi_unregister(scsihost);
@@ -557,7 +577,7 @@
}
if (check_region(hostdata->io_base, 0xff)) {
- printk("qlogicisp : i/o region 0x%04lx-0x%04lx already in use\n",
+ printk("qlogicisp : i/o region 0x%04x-0x%04x already in use\n",
hostdata->io_base, hostdata->io_base + 0xff);
free_irq(hostdata->irq, NULL);
scsi_unregister(scsihost);
@@ -567,6 +587,8 @@
request_region(hostdata->io_base, 0xff, "qlogicisp");
irq2host[hostdata->irq] = hostdata;
+ outw(0x0, hostdata->io_base + PCI_SEMAPHORE);
+ outw(HCCR_CLEAR_RISC_INTR, hostdata->io_base + HOST_HCCR);
isp1020_enable_irqs(hostdata);
hosts++;
@@ -605,8 +627,9 @@
ENTER("isp1020_info");
hostdata = (struct isp1020_hostdata *) host->hostdata;
- sprintf(buf, "QLogic ISP1020 SCSI on PCI bus %d, device %d, irq %d",
- hostdata->bus, (hostdata->device_fn & 0xf8) >> 3, hostdata->irq);
+ sprintf(buf, "QLogic ISP1020 SCSI on PCI bus %d device %d irq %d base 0x%x",
+ hostdata->bus, (hostdata->device_fn & 0xf8) >> 3, hostdata->irq,
+ hostdata->io_base);
LEAVE("isp1020_info");
@@ -627,6 +650,7 @@
struct scatterlist *sg;
struct Command_Entry *cmd;
struct isp1020_hostdata *hostdata;
+ unsigned long flags;
ENTER("isp1020_queuecommand");
@@ -635,10 +659,14 @@
DEBUG(isp1020_print_scsi_cmd(Cmnd);)
+ save_flags(flags);
+ cli();
+
hostdata->req_queue_out_ptr = inw(hostdata->io_base + MBOX4);
if ((hostdata->req_queue_in_ptr + 1) % REQ_QUEUE_LEN ==
hostdata->req_queue_out_ptr) {
+ restore_flags(flags);
printk("qlogicisp : request queue overflow\n");
return 1;
}
@@ -653,11 +681,12 @@
cmd->hdr.entry_type = ENTRY_COMMAND;
cmd->hdr.entry_cnt = 1;
- cmd->handle = (caddr_t) Cmnd;
+ cmd->handle = (u_int) virt_to_bus(Cmnd);
cmd->target_lun = Cmnd->lun;
cmd->target_id = Cmnd->target;
cmd->cdb_length = Cmnd->cmd_len;
cmd->control_flags = CFLAG_READ | CFLAG_WRITE;
+ cmd->time_out = 30;
for (i = 0; i < Cmnd->cmd_len; i++)
cmd->cdb[i] = Cmnd->cmnd[i];
@@ -668,13 +697,13 @@
iptr = (int *) &cmd->dataseg0.d_base;
for (i = 0; sg_count > 0; sg_count--, i++) {
- *iptr++ = (int) sg[i].address;
+ *iptr++ = (int) virt_to_bus(sg[i].address);
*iptr++ = sg[i].length;
}
}
else {
- cmd->dataseg0.d_base = (caddr_t) Cmnd->request_buffer;
- cmd->dataseg0.d_count = (u_long) Cmnd->request_bufflen;
+ cmd->dataseg0.d_base = (u_int) virt_to_bus(Cmnd->request_buffer);
+ cmd->dataseg0.d_count = (u_int) Cmnd->request_bufflen;
cmd->segment_cnt = 1;
}
@@ -683,6 +712,8 @@
outw(hostdata->req_queue_in_ptr, hostdata->io_base + MBOX4);
+ restore_flags(flags);
+
LEAVE("isp1020_queuecommand");
return 0;
@@ -701,6 +732,7 @@
u_short param[6];
struct isp1020_hostdata *hostdata;
int return_status = SCSI_ABORT_SUCCESS;
+ u_int cmdaddr = virt_to_bus(Cmnd);
ENTER("isp1020_abort");
@@ -712,8 +744,8 @@
param[0] = MBOX_ABORT;
param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
- param[2] = (u_long) Cmnd >> 16;
- param[3] = (u_long) Cmnd & 0xffff;
+ param[2] = cmdaddr >> 16;
+ param[3] = cmdaddr & 0xffff;
isp1020_mbox_command(hostdata, param);
@@ -730,7 +762,7 @@
}
-int isp1020_reset(Scsi_Cmnd *Cmnd)
+int isp1020_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags)
{
u_short param[6];
struct isp1020_hostdata *hostdata;
@@ -756,11 +788,11 @@
LEAVE("isp1020_reset");
- return SCSI_RESET_SUCCESS;
+ return return_status;;
}
-int isp1020_biosparam(Disk *disk, int n, int ip[])
+int isp1020_biosparam(Disk *disk, kdev_t n, int ip[])
{
int size = disk->capacity;
@@ -786,16 +818,22 @@
int isp1020_reset_hardware(struct isp1020_hostdata *hostdata)
{
u_short param[6];
+ int loop_count;
ENTER("isp1020_reset_hardware");
- outw(0x0001, hostdata->io_base + PCI_INTF_CTL);
+ outw(ISP_RESET, hostdata->io_base + PCI_INTF_CTL);
outw(HCCR_RESET, hostdata->io_base + HOST_HCCR);
outw(HCCR_RELEASE, hostdata->io_base + HOST_HCCR);
- outw(HCCR_BIOS_ENABLE, hostdata->io_base + HOST_HCCR);
+ outw(HCCR_BIOS_DISABLE, hostdata->io_base + HOST_HCCR);
- while (inw(hostdata->io_base + MBOX0))
+ loop_count = DEFAULT_LOOP_COUNT;
+ while (--loop_count && inw(hostdata->io_base + HOST_HCCR) == RISC_BUSY)
barrier();
+ if (!loop_count)
+ printk("qlogicisp: reset_hardware loop timeout\n");
+
+ outw(0, hostdata->io_base + ISP_CFG1);
#if DEBUG_ISP1020
printk("qlogicisp : mbox 0 0x%04x \n", inw(hostdata->io_base + MBOX0));
@@ -864,7 +902,7 @@
int isp1020_init(struct Scsi_Host *sh)
{
- u_long io_base;
+ u_int io_base;
struct isp1020_hostdata *hostdata;
u_char bus, device_fn, revision, irq;
u_short vendor_id, device_id, command;
@@ -914,7 +952,7 @@
}
if (revision != ISP1020_REV_ID)
- printk("qlogicisp : warning : new isp1020 revision id\n");
+ printk("qlogicisp : new isp1020 revision ID (%d)\n", revision);
if (inw(io_base + PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC
|| inw(io_base + PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020) {
@@ -941,7 +979,8 @@
if (!isp1020_verify_nvram(hostdata)) {
printk("qlogicisp : nvram checksum failure\n");
- return 1;
+ printk("qlogicisp : attempting to use default parameters\n");
+ return isp1020_set_defaults(hostdata);
}
value = isp1020_read_nvram_word(hostdata, 2);
@@ -999,7 +1038,7 @@
hostdata->host_param.max_queue_depth);
#endif /* DEBUG_ISP1020_SETUP */
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < MAX_TARGETS; i++) {
value = isp1020_read_nvram_word(hostdata, 14 + i * 3);
hostdata->dev_param[i].device_flags = value & 0xff;
@@ -1042,7 +1081,7 @@
hostdata->host_param.initiator_scsi_id = 7;
hostdata->host_param.bus_reset_delay = 3;
hostdata->host_param.retry_count = 0;
- hostdata->host_param.retry_delay = 0;
+ hostdata->host_param.retry_delay = 1;
hostdata->host_param.async_data_setup_time = 6;
hostdata->host_param.req_ack_active_negation = 1;
hostdata->host_param.data_line_active_negation = 1;
@@ -1052,8 +1091,8 @@
hostdata->host_param.selection_timeout = 250;
hostdata->host_param.max_queue_depth = 256;
- for (i = 0; i < 16; i++) {
- hostdata->dev_param[i].device_flags = 0xc4;
+ for (i = 0; i < MAX_TARGETS; i++) {
+ hostdata->dev_param[i].device_flags = 0xfd;
hostdata->dev_param[i].execution_throttle = 16;
hostdata->dev_param[i].synchronous_period = 25;
hostdata->dev_param[i].synchronous_offset = 12;
@@ -1069,12 +1108,16 @@
int isp1020_load_parameters(struct isp1020_hostdata *hostdata)
{
int i, k;
- u_long queue_addr;
+ u_int queue_addr;
u_short param[6];
u_short isp_cfg1;
+ unsigned long flags;
ENTER("isp1020_load_parameters");
+ save_flags(flags);
+ cli();
+
outw(hostdata->host_param.fifo_threshold, hostdata->io_base + ISP_CFG1);
param[0] = MBOX_SET_INIT_SCSI_ID;
@@ -1083,6 +1126,7 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set initiator id failure\n");
return 1;
}
@@ -1094,6 +1138,7 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set retry count failure\n");
return 1;
}
@@ -1104,6 +1149,7 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : async data setup time failure\n");
return 1;
}
@@ -1115,6 +1161,7 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set active negation state failure\n");
return 1;
}
@@ -1126,6 +1173,7 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set pci control parameter failure\n");
return 1;
}
@@ -1146,6 +1194,7 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set tag age limit failure\n");
return 1;
}
@@ -1156,11 +1205,12 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set selection timeout failure\n");
return 1;
}
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < MAX_TARGETS; i++) {
if (!hostdata->dev_param[i].device_enable)
continue;
@@ -1174,11 +1224,12 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set target parameter failure\n");
return 1;
}
- for (k = 0; k < 8; k++) {
+ for (k = 0; k < MAX_LUNS; k++) {
param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
param[1] = (i << 8) | k;
@@ -1188,13 +1239,14 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set device queue parameter failure\n");
return 1;
}
}
}
- queue_addr = (u_long) &hostdata->res_queue[0][0];
+ queue_addr = (u_int) virt_to_bus(&hostdata->res_queue[0][0]);
param[0] = MBOX_INIT_RES_QUEUE;
param[1] = RES_QUEUE_LEN;
@@ -1206,11 +1258,12 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set response queue failure\n");
return 1;
}
- queue_addr = (u_long) &hostdata->req_queue[0][0];
+ queue_addr = (u_int) virt_to_bus(&hostdata->req_queue[0][0]);
param[0] = MBOX_INIT_REQ_QUEUE;
param[1] = REQ_QUEUE_LEN;
@@ -1221,23 +1274,35 @@
isp1020_mbox_command(hostdata, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
+ restore_flags(flags);
printk("qlogicisp : set request queue failure\n");
return 1;
}
+ restore_flags(flags);
+
LEAVE("isp1020_load_parameters");
return 0;
}
+/*
+ * currently, this is only called during initialization or abort/reset,
+ * at which times interrupts are disabled, so polling is OK, I guess...
+ */
int isp1020_mbox_command(struct isp1020_hostdata *hostdata, u_short param[])
{
+ int loop_count;
+
if (mbox_param[param[0]] == 0)
return 1;
- while (inw(hostdata->io_base + HOST_HCCR) & 0x0080)
+ loop_count = DEFAULT_LOOP_COUNT;
+ while (--loop_count && inw(hostdata->io_base + HOST_HCCR) & 0x0080)
barrier();
+ if (!loop_count)
+ printk("qlogicisp: mbox_command loop timeout #1\n");
switch(mbox_param[param[0]] >> 4) {
case 6: outw(param[5], hostdata->io_base + MBOX5);
@@ -1248,19 +1313,21 @@
case 1: outw(param[0], hostdata->io_base + MBOX0);
}
- outw(HCCR_CLEAR_RISC_INTR, hostdata->io_base + HOST_HCCR);
outw(0x0, hostdata->io_base + PCI_SEMAPHORE);
-
+ outw(HCCR_CLEAR_RISC_INTR, hostdata->io_base + HOST_HCCR);
outw(HCCR_SET_HOST_INTR, hostdata->io_base + HOST_HCCR);
- while (!(inw(hostdata->io_base + PCI_INTF_STS) & 0x04))
+ loop_count = DEFAULT_LOOP_COUNT;
+ while (--loop_count && !(inw(hostdata->io_base + PCI_INTF_STS) & 0x04))
barrier();
+ if (!loop_count)
+ printk("qlogicisp: mbox_command loop timeout #2\n");
- while (inw(hostdata->io_base + MBOX0) == 0x04)
+ loop_count = DEFAULT_LOOP_COUNT;
+ while (--loop_count && inw(hostdata->io_base + MBOX0) == 0x04)
barrier();
-
- outw(HCCR_CLEAR_RISC_INTR, hostdata->io_base + HOST_HCCR);
- outw(0x0, hostdata->io_base + PCI_SEMAPHORE);
+ if (!loop_count)
+ printk("qlogicisp: mbox_command loop timeout #3\n");
switch(mbox_param[param[0]] & 0xf) {
case 6: param[5] = inw(hostdata->io_base + MBOX5);
@@ -1271,19 +1338,23 @@
case 1: param[0] = inw(hostdata->io_base + MBOX0);
}
+ outw(0x0, hostdata->io_base + PCI_SEMAPHORE);
+ outw(HCCR_CLEAR_RISC_INTR, hostdata->io_base + HOST_HCCR);
+
return 0;
}
-#define RESPONSE_QUEUE_UPDATE 0x01
+#define MAILBOX_INTERRUPT 0x01
-void isp1020_intr_handler(int irq, struct pt_regs *regs)
+void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
{
Scsi_Cmnd *Cmnd;
struct Status_Entry *sts;
struct Marker_Entry *marker;
u_short status, add_marker = 0;
struct isp1020_hostdata *hostdata;
+ int loop_count;
ENTER_INTR("isp1020_intr_handler");
@@ -1294,14 +1365,18 @@
DEBUG_INTR(printk("qlogicisp : interrupt on line %d\n", irq);)
- while (!(inw(hostdata->io_base + PCI_INTF_STS) & 0x04))
+ loop_count = DEFAULT_LOOP_COUNT;
+ while (--loop_count && !(inw(hostdata->io_base + PCI_INTF_STS) & 0x04))
barrier();
+ if (!loop_count)
+ printk("qlogicisp: intr_handler loop timeout\n");
- hostdata->res_queue_in_ptr = inw(hostdata->io_base + MBOX5);
- outw(HCCR_CLEAR_RISC_INTR, hostdata->io_base + HOST_HCCR);
status = inw(hostdata->io_base + PCI_SEMAPHORE);
- if ((status & RESPONSE_QUEUE_UPDATE) == 0) {
+ if ((status & MAILBOX_INTERRUPT) == 0) {
+
+ hostdata->res_queue_in_ptr = inw(hostdata->io_base + MBOX5);
+ outw(HCCR_CLEAR_RISC_INTR, hostdata->io_base + HOST_HCCR);
DEBUG_INTR(printk("qlogicisp : response queue update\n");)
DEBUG_INTR(printk("qlogicisp : response queue depth %d\n",
@@ -1312,7 +1387,7 @@
sts = (struct Status_Entry *)
&hostdata->res_queue[hostdata->res_queue_out_ptr][0];
- Cmnd = (Scsi_Cmnd *) sts->handle;
+ Cmnd = (Scsi_Cmnd *) bus_to_virt(sts->handle);
if (sts->completion_status == CS_RESET_OCCURRED
|| sts->completion_status == CS_ABORTED
@@ -1321,7 +1396,7 @@
if (sts->state_flags & SF_GOT_SENSE)
memcpy(Cmnd->sense_buffer, sts->req_sense_data,
- sizeof(Cmnd->sense_buffer));
+ sizeof(Cmnd->sense_buffer));
DEBUG_INTR(isp1020_print_status_entry(sts);)
@@ -1340,10 +1415,7 @@
}
else {
- DEBUG_INTR(printk("qlogicisp : mbox completion\n");)
-
status = inw(hostdata->io_base + MBOX0);
- outw(0x0, hostdata->io_base + PCI_SEMAPHORE);
DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n", status);)
@@ -1359,14 +1431,26 @@
printk("qlogicisp : bad mailbox return status\n");
break;
}
+
+ outw(0x0, hostdata->io_base + PCI_SEMAPHORE);
+ outw(HCCR_CLEAR_RISC_INTR, hostdata->io_base + HOST_HCCR);
}
if (add_marker) {
+#if 0
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+#endif
DEBUG_INTR(printk("qlogicisp : adding marker entry\n");)
if ((hostdata->req_queue_in_ptr + 1) % REQ_QUEUE_LEN
== hostdata->req_queue_out_ptr) {
+#if 0
+ restore_flags(flags);
+#endif
printk("qlogicisp : request queue overflow\n");
return;
}
@@ -1384,14 +1468,19 @@
% REQ_QUEUE_LEN;
outw(hostdata->req_queue_in_ptr, hostdata->io_base + MBOX4);
+
+#if 0
+ restore_flags(flags);
+#endif
}
+ isp1020_enable_irqs(hostdata);
+
LEAVE_INTR("isp1020_intr_handler");
}
-#define NVRAM_DELAY() { \
- int counter = 0; while (counter++ < 0xc8) barrier(); }
+#define NVRAM_DELAY() udelay(2) /* 2 microsecond delay */
u_short isp1020_read_nvram_word(struct isp1020_hostdata *hostdata, u_short byte)
@@ -1409,14 +1498,14 @@
}
for (i = 0xf, value = 0; i >= 0; i--) {
- value = value << 0x1;
+ value <<= 1;
outw(0x3, hostdata->io_base + PCI_NVRAM); NVRAM_DELAY();
input = inw(hostdata->io_base + PCI_NVRAM); NVRAM_DELAY();
outw(0x2, hostdata->io_base + PCI_NVRAM); NVRAM_DELAY();
- if (input & 0x8) value |= 0x1;
+ if (input & 0x8) value |= 1;
}
- outw(0x0, hostdata->io_base + PCI_NVRAM);
+ outw(0x0, hostdata->io_base + PCI_NVRAM); NVRAM_DELAY();
return(value);
}
@@ -1455,7 +1544,7 @@
void isp1020_enable_irqs(struct isp1020_hostdata *hostdata)
{
- outw(0x6, hostdata->io_base + PCI_INTF_CTL);
+ outw(ISP_EN_INT|ISP_EN_RISC, hostdata->io_base + PCI_INTF_CTL);
}
@@ -1479,7 +1568,7 @@
status->state_flags, status->status_flags);
printk("qlogicisp : time = 0x%04x, request sense length = 0x%04x\n",
status->time, status->req_sense_len);
- printk("qlogicisp : residual transfer length = 0x%08lx\n", status->residual);
+ printk("qlogicisp : residual transfer length = 0x%08x\n", status->residual);
for (i = 0; i < status->req_sense_len; i++)
printk("qlogicisp : sense data = 0x%02x\n", status->req_sense_data[i]);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this