QLogic ISP1020 SCSI driver worked.
Ryuichi Oikawa
roikawa at rr.iij4u.or.jp
Fri Dec 11 02:27:00 EST 1998
Hello all,
Qlogic ISP1020 SCSI driver worked by applying the patch listed below.
Regards,
Ryuichi Oikawa
roikawa at rr.iij4u.or.jp
--- qlogicisp.c.orig Sun Oct 11 04:37:47 1998
+++ qlogicisp.c Thu Dec 10 23:36:32 1998
@@ -32,6 +32,16 @@
#include "hosts.h"
#include "qlogicisp.h"
+#if defined(CONFIG_PPC)
+#if !defined(__IPS1020_MMIO)
+#define __ISP1020_MMIO 1
+#endif
+#undef inw
+#undef outw
+#define inw(port) in_le16((unsigned short *)(port))
+#define outw(val, port) out_le16((unsigned short *)(port), (val))
+#endif
+
/* Configuration section *****************************************************/
/* Set the following macro to 1 to reload the ISP1020's firmware. This is
@@ -49,7 +59,7 @@
/* Macros used for debugging */
#define DEBUG_ISP1020 0
-#define DEBUG_ISP1020_INT 0
+#define DEBUG_ISP1020_INTR 0
#define DEBUG_ISP1020_SETUP 0
#define TRACE_ISP 0
@@ -113,6 +123,8 @@
#define DEBUG_INTR(x)
#endif /* DEBUG ISP1020_INTR */
+#define PCI_VENDOR_ID_QLOGIC 0x1077
+#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
#define ISP1020_REV_ID 1
#define MAX_TARGETS 16
@@ -539,6 +551,21 @@
S_IFDIR | S_IRUGO | S_IXUGO, 2
};
+#if defined(__BIG_ENDIAN)
+static inline unsigned long endian_reverse32(unsigned long val)
+{
+ unsigned char *p = (unsigned char *)&val;
+ return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0));
+}
+static inline unsigned short endian_reverse16(unsigned long val)
+{
+ unsigned char *p = (unsigned char *)&val;
+ return ((p[3] << 8) | (p[2] << 0));
+}
+#else
+#define endian_reverse32(val) (val)
+#define endian_reverse16(val) (val)
+#endif
static inline void isp1020_enable_irqs(struct Scsi_Host *host)
{
@@ -598,6 +625,7 @@
continue;
}
+#if !defined(__ISP1020_MMIO)
if (check_region(host->io_port, 0xff)) {
printk("qlogicisp : i/o region 0x%lx-0x%lx already "
"in use\n",
@@ -608,6 +636,7 @@
}
request_region(host->io_port, 0xff, "qlogicisp");
+#endif
outw(0x0, host->io_port + PCI_SEMAPHORE);
outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
@@ -633,7 +662,11 @@
outw(0x0, host->io_port + PCI_INTF_CTL);
free_irq(host->irq, host);
+#if defined(__ISP1020_MMIO)
+ iounmap(host->io_port);
+#else
release_region(host->io_port, 0xff);
+#endif
LEAVE("isp1020_release");
@@ -730,17 +763,18 @@
cmd->hdr.entry_type = ENTRY_COMMAND;
cmd->hdr.entry_cnt = 1;
- cmd->handle = (u_int) virt_to_bus(Cmnd);
+ cmd->handle = endian_reverse32(__pa(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;
+ cmd->cdb_length = endian_reverse16(Cmnd->cmd_len);
+ cmd->control_flags = endian_reverse16(CFLAG_READ | CFLAG_WRITE);
+ cmd->time_out = endian_reverse16(30);
memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
if (Cmnd->use_sg) {
- cmd->segment_cnt = sg_count = Cmnd->use_sg;
+ sg_count = Cmnd->use_sg;
+ cmd->segment_cnt = endian_reverse16(sg_count);
sg = (struct scatterlist *) Cmnd->request_buffer;
ds = cmd->dataseg;
@@ -749,8 +783,8 @@
if (n > 4)
n = 4;
for (i = 0; i < n; i++) {
- ds[i].d_base = (u_int) virt_to_bus(sg->address);
- ds[i].d_count = sg->length;
+ ds[i].d_base = endian_reverse32(__pa(sg->address));
+ ds[i].d_count = endian_reverse32(sg->length);
++sg;
}
sg_count -= 4;
@@ -770,24 +804,22 @@
cont->hdr.entry_cnt = 0;
cont->hdr.sys_def_1 = 0;
cont->hdr.flags = 0;
- cont->reserved = 0;
+ cont->reserved = endian_reverse32(0);
ds = cont->dataseg;
n = sg_count;
if (n > 7)
n = 7;
for (i = 0; i < n; ++i) {
- ds[i].d_base = (u_int)virt_to_bus(sg->address);
- ds[i].d_count = sg->length;
+ ds[i].d_base = endian_reverse32(__pa(sg->address));
+ ds[i].d_count = endian_reverse32(sg->length);
++sg;
}
sg_count -= n;
}
} else {
- cmd->dataseg[0].d_base =
- (u_int) virt_to_bus(Cmnd->request_buffer);
- cmd->dataseg[0].d_count =
- (u_int) Cmnd->request_bufflen;
- cmd->segment_cnt = 1;
+ cmd->dataseg[0].d_base = endian_reverse32(__pa(Cmnd->request_buffer));
+ cmd->dataseg[0].d_count = endian_reverse32(Cmnd->request_bufflen);
+ cmd->segment_cnt = endian_reverse16(1);
}
outw(in_ptr, host->io_port + MBOX4);
@@ -861,22 +893,23 @@
DEBUG_INTR(printk("qlogicisp : response queue update\n"));
DEBUG_INTR(printk("qlogicisp : response queue depth %d\n",
- QUEUE_DEPTH(in_ptr, out_ptr)));
+ RES_QUEUE_DEPTH(in_ptr, out_ptr)));
while (out_ptr != in_ptr) {
sts = (struct Status_Entry *) &hostdata->res[out_ptr][0];
out_ptr = (out_ptr + 1) & RES_QUEUE_LEN;
- Cmnd = (Scsi_Cmnd *) bus_to_virt(sts->handle);
+ Cmnd = (Scsi_Cmnd *)__va(endian_reverse32(sts->handle));
TRACE("done", out_ptr, Cmnd);
- if (sts->completion_status == CS_RESET_OCCURRED
- || sts->completion_status == CS_ABORTED
- || (sts->status_flags & STF_BUS_RESET))
+ status = endian_reverse16(sts->completion_status);
+ if (status == CS_RESET_OCCURRED
+ || status == CS_ABORTED
+ || (endian_reverse16(sts->status_flags) & STF_BUS_RESET))
hostdata->send_marker = 1;
- if (sts->state_flags & SF_GOT_SENSE)
+ if (endian_reverse16(sts->state_flags) & SF_GOT_SENSE)
memcpy(Cmnd->sense_buffer, sts->req_sense_data,
sizeof(Cmnd->sense_buffer));
@@ -913,28 +946,29 @@
"DID_BAD_INTR"
};
#endif /* DEBUG_ISP1020_INTR */
+ u_short state_flags = endian_reverse16(sts->state_flags);
ENTER("isp1020_return_status");
DEBUG(printk("qlogicisp : completion status = 0x%04x\n",
- sts->completion_status));
+ endian_reverse16(sts->completion_status)));
- switch(sts->completion_status) {
+ switch(endian_reverse16(sts->completion_status)) {
case CS_COMPLETE:
host_status = DID_OK;
break;
case CS_INCOMPLETE:
- if (!(sts->state_flags & SF_GOT_BUS))
+ if (!(state_flags & SF_GOT_BUS))
host_status = DID_NO_CONNECT;
- else if (!(sts->state_flags & SF_GOT_TARGET))
+ else if (!(state_flags & SF_GOT_TARGET))
host_status = DID_BAD_TARGET;
- else if (!(sts->state_flags & SF_SENT_CDB))
+ else if (!(state_flags & SF_SENT_CDB))
host_status = DID_ERROR;
- else if (!(sts->state_flags & SF_TRANSFERRED_DATA))
+ else if (!(state_flags & SF_TRANSFERRED_DATA))
host_status = DID_ERROR;
- else if (!(sts->state_flags & SF_GOT_STATUS))
+ else if (!(state_flags & SF_GOT_STATUS))
host_status = DID_ERROR;
- else if (!(sts->state_flags & SF_GOT_SENSE))
+ else if (!(state_flags & SF_GOT_SENSE))
host_status = DID_ERROR;
break;
case CS_DMA_ERROR:
@@ -970,17 +1004,17 @@
break;
default:
printk("qlogicisp : unknown completion status 0x%04x\n",
- sts->completion_status);
+ endian_reverse16(sts->completion_status));
host_status = DID_ERROR;
break;
}
DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n",
- reason[host_status], sts->scsi_status));
+ reason[host_status], endian_reverse16(sts->scsi_status)));
LEAVE("isp1020_return_status");
- return (sts->scsi_status & STATUS_MASK) | (host_status << 16);
+ return (endian_reverse16(sts->scsi_status) & STATUS_MASK) | (host_status << 16);
}
@@ -990,7 +1024,7 @@
struct Scsi_Host *host;
struct isp1020_hostdata *hostdata;
int return_status = SCSI_ABORT_SUCCESS;
- u_int cmdaddr = virt_to_bus(Cmnd);
+ u_int cmdaddr = __pa(Cmnd);
ENTER("isp1020_abort");
@@ -1184,7 +1218,18 @@
printk("qlogicisp : error reading PCI configuration\n");
return 1;
}
+#if defined(CONFIG_PPC)
+ command |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
+ | PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE;
+ pci_write_config_word(pdev, PCI_COMMAND, command);
+#endif
+#if defined(__ISP1020_MMIO)
+ io_base = (unsigned long)ioremap(pdev->base_address[1], 0x1000);
+ printk("qlogicisp: MMIO 0x%08x mapped at 0x%08x\n",
+ pdev->base_address[1], io_base);
+#else
io_base = pdev->base_address[0];
+#endif
irq = pdev->irq;
if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {
@@ -1199,17 +1244,23 @@
return 1;
}
+#if !defined(__ISP1020_MMIO)
if (command & PCI_COMMAND_IO && (io_base & 3) == 1)
io_base &= PCI_BASE_ADDRESS_IO_MASK;
else {
printk("qlogicisp : i/o mapping is disabled\n");
return 1;
}
+#endif
+#if defined(CONFIG_PPC)
+ /* Already set PCI_COMMAND_MASTER */
+#else
if (!(command & PCI_COMMAND_MASTER)) {
printk("qlogicisp : bus mastering is disabled\n");
return 1;
}
+#endif
if (revision != ISP1020_REV_ID)
printk("qlogicisp : new isp1020 revision ID (%d)\n", revision);
@@ -1217,7 +1268,7 @@
if (inw(io_base + PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC
|| inw(io_base + PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020)
{
- printk("qlogicisp : can't decode i/o address space 0x%lx\n",
+ printk("qlogicisp : can't decode (mm)i/o address space 0x%lx\n",
io_base);
return 1;
}
@@ -1582,7 +1633,7 @@
}
}
- queue_addr = (u_int) virt_to_bus(&hostdata->res[0][0]);
+ queue_addr = (u_int)__pa(&hostdata->res[0][0]);
param[0] = MBOX_INIT_RES_QUEUE;
param[1] = RES_QUEUE_LEN + 1;
@@ -1599,7 +1650,7 @@
return 1;
}
- queue_addr = (u_int) virt_to_bus(&hostdata->req[0][0]);
+ queue_addr = (u_int)__pa(&hostdata->req[0][0]);
param[0] = MBOX_INIT_REQ_QUEUE;
param[1] = QLOGICISP_REQ_QUEUE_LEN + 1;
[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request at lists.linuxppc.org ]]
More information about the Linuxppc-dev
mailing list