patch-2.3.99-pre3 linux/drivers/scsi/qlogicisp.c
Next file: linux/drivers/scsi/scsi.c
Previous file: linux/drivers/scsi/eata.c
Back to the patch index
Back to the overall index
- Lines: 305
- Date:
Wed Mar 22 00:05:02 2000
- Orig file:
v2.3.99-pre2/linux/drivers/scsi/qlogicisp.c
- Orig date:
Sun Feb 20 21:12:39 2000
diff -u --recursive --new-file v2.3.99-pre2/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
@@ -6,6 +6,9 @@
* Copyright 2000, Jayson C. Vantuyl <vantuyl@csc.smsu.edu>
* and Bryon W. Roche <bryon@csc.smsu.edu>
*
+ * 64-bit addressing added by Kanoj Sarcar <kanoj@sgi.com>
+ * and Leo Dagum <dagum@sgi.com>
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
@@ -18,6 +21,7 @@
*/
#include <linux/blk.h>
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
@@ -160,6 +164,8 @@
#define MBOX3 0x76 /* mailbox 3 */
#define MBOX4 0x78 /* mailbox 4 */
#define MBOX5 0x7a /* mailbox 5 */
+#define MBOX6 0x7c /* mailbox 6 */
+#define MBOX7 0x7e /* mailbox 7 */
/* mailbox command complete status codes */
#define MBOX_COMMAND_COMPLETE 0x4000
@@ -177,6 +183,15 @@
#define REQUEST_QUEUE_WAKEUP 0x8005
#define EXECUTION_TIMEOUT_RESET 0x8006
+#ifdef CONFIG_QL_ISP_A64
+#define IOCB_SEGS 2
+#define CONTINUATION_SEGS 5
+#define MAX_CONTINUATION_ENTRIES 254
+#else
+#define IOCB_SEGS 4
+#define CONTINUATION_SEGS 7
+#endif /* CONFIG_QL_ISP_A64 */
+
struct Entry_header {
u_char entry_type;
u_char entry_cnt;
@@ -185,8 +200,14 @@
};
/* entry header type commands */
+#ifdef CONFIG_QL_ISP_A64
+#define ENTRY_COMMAND 9
+#define ENTRY_CONTINUATION 0xa
+#else
#define ENTRY_COMMAND 1
#define ENTRY_CONTINUATION 2
+#endif /* CONFIG_QL_ISP_A64 */
+
#define ENTRY_STATUS 3
#define ENTRY_MARKER 4
#define ENTRY_EXTENDED_COMMAND 5
@@ -199,6 +220,9 @@
struct dataseg {
u_int d_base;
+#ifdef CONFIG_QL_ISP_A64
+ u_int d_base_hi;
+#endif
u_int d_count;
};
@@ -213,7 +237,11 @@
u_short time_out;
u_short segment_cnt;
u_char cdb[12];
- struct dataseg dataseg[4];
+#ifdef CONFIG_QL_ISP_A64
+ u_int rsvd1;
+ u_int rsvd2;
+#endif
+ struct dataseg dataseg[IOCB_SEGS];
};
/* command entry control flag definitions */
@@ -240,8 +268,10 @@
struct Continuation_Entry {
struct Entry_header hdr;
+#ifndef CONFIG_QL_ISP_A64
u_int reserved;
- struct dataseg dataseg[7];
+#endif
+ struct dataseg dataseg[CONTINUATION_SEGS];
};
struct Marker_Entry {
@@ -385,6 +415,11 @@
#define MBOX_WRITE_FOUR_RAM_WORDS 0x0041
#define MBOX_EXEC_BIOS_IOCB 0x0042
+#ifdef CONFIG_QL_ISP_A64
+#define MBOX_CMD_INIT_REQUEST_QUEUE_64 0x0052
+#define MBOX_CMD_INIT_RESPONSE_QUEUE_64 0x0053
+#endif /* CONFIG_QL_ISP_A64 */
+
#include "qlogicisp_asm.c"
#define PACKB(a, b) (((a)<<4)|(b))
@@ -457,6 +492,25 @@
PACKB(1, 2), /* MBOX_RETURN_BIOS_BLOCK_ADDR */
PACKB(6, 1), /* MBOX_WRITE_FOUR_RAM_WORDS */
PACKB(2, 3) /* MBOX_EXEC_BIOS_IOCB */
+#ifdef CONFIG_QL_ISP_A64
+ ,PACKB(0, 0), /* 0x0043 */
+ PACKB(0, 0), /* 0x0044 */
+ PACKB(0, 0), /* 0x0045 */
+ PACKB(0, 0), /* 0x0046 */
+ PACKB(0, 0), /* 0x0047 */
+ PACKB(0, 0), /* 0x0048 */
+ PACKB(0, 0), /* 0x0049 */
+ PACKB(0, 0), /* 0x004a */
+ PACKB(0, 0), /* 0x004b */
+ PACKB(0, 0), /* 0x004c */
+ PACKB(0, 0), /* 0x004d */
+ PACKB(0, 0), /* 0x004e */
+ PACKB(0, 0), /* 0x004f */
+ PACKB(0, 0), /* 0x0050 */
+ PACKB(0, 0), /* 0x0051 */
+ PACKB(8, 8), /* MBOX_CMD_INIT_REQUEST_QUEUE_64 (0x0052) */
+ PACKB(8, 8) /* MBOX_CMD_INIT_RESPONSE_QUEUE_64 (0x0053) */
+#endif /* CONFIG_QL_ISP_A64 */
};
#define MAX_MBOX_COMMAND (sizeof(mbox_param)/sizeof(u_short))
@@ -742,6 +796,7 @@
struct Continuation_Entry *cont;
struct Scsi_Host *host;
struct isp1020_hostdata *hostdata;
+ dma_addr_t dma_addr;
ENTER("isp1020_queuecommand");
@@ -817,14 +872,18 @@
/* fill in first four sg entries: */
n = sg_count;
- if (n > 4)
- n = 4;
+ if (n > IOCB_SEGS)
+ n = IOCB_SEGS;
for (i = 0; i < n; i++) {
- ds[i].d_base = cpu_to_le32(sg_dma_address(sg));
+ dma_addr = sg_dma_address(sg);
+ ds[i].d_base = cpu_to_le32((u32) dma_addr);
+#ifdef CONFIG_QL_ISP_A64
+ ds[i].d_base_hi = cpu_to_le32((u32) (dma_addr>>32));
+#endif /* CONFIG_QL_ISP_A64 */
ds[i].d_count = cpu_to_le32(sg_dma_len(sg));
++sg;
}
- sg_count -= 4;
+ sg_count -= IOCB_SEGS;
while (sg_count > 0) {
++cmd->hdr.entry_cnt;
@@ -841,32 +900,46 @@
cont->hdr.entry_cnt = 0;
cont->hdr.sys_def_1 = 0;
cont->hdr.flags = 0;
+#ifndef CONFIG_QL_ISP_A64
cont->reserved = 0;
+#endif
ds = cont->dataseg;
n = sg_count;
- if (n > 7)
- n = 7;
+ if (n > CONTINUATION_SEGS)
+ n = CONTINUATION_SEGS;
for (i = 0; i < n; ++i) {
- ds[i].d_base = cpu_to_le32(sg_dma_address(sg));
+ dma_addr = sg_dma_address(sg);
+ ds[i].d_base = cpu_to_le32((u32) dma_addr);
+#ifdef CONFIG_QL_ISP_A64
+ ds[i].d_base_hi = cpu_to_le32((u32)(dma_addr>>32));
+#endif /* CONFIG_QL_ISP_A64 */
ds[i].d_count = cpu_to_le32(sg_dma_len(sg));
++sg;
}
sg_count -= n;
}
} else if (Cmnd->request_bufflen) {
- Cmnd->SCp.ptr = (char *)(unsigned long)
- pci_map_single(hostdata->pci_dev,
+ /*Cmnd->SCp.ptr = (char *)(unsigned long)*/
+ dma_addr = pci_map_single(hostdata->pci_dev,
Cmnd->request_buffer,
Cmnd->request_bufflen,
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ Cmnd->SCp.ptr = (char *)(unsigned long) dma_addr;
cmd->dataseg[0].d_base =
- cpu_to_le32((u32)(long)Cmnd->SCp.ptr);
+ cpu_to_le32((u32) dma_addr);
+#ifdef CONFIG_QL_ISP_A64
+ cmd->dataseg[0].d_base_hi =
+ cpu_to_le32((u32) (dma_addr>>32));
+#endif /* CONFIG_QL_ISP_A64 */
cmd->dataseg[0].d_count =
cpu_to_le32((u32)Cmnd->request_bufflen);
cmd->segment_cnt = cpu_to_le16(1);
} else {
cmd->dataseg[0].d_base = 0;
+#ifdef CONFIG_QL_ISP_A64
+ cmd->dataseg[0].d_base_hi = 0;
+#endif /* CONFIG_QL_ISP_A64 */
cmd->dataseg[0].d_count = 0;
cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */
}
@@ -983,7 +1056,11 @@
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
else if (Cmnd->request_bufflen)
pci_unmap_single(hostdata->pci_dev,
+#ifdef CONFIG_QL_ISP_A64
+ (dma_addr_t)((long)Cmnd->SCp.ptr),
+#else
(u32)((long)Cmnd->SCp.ptr),
+#endif
Cmnd->request_bufflen,
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
@@ -1612,8 +1689,13 @@
static int isp1020_load_parameters(struct Scsi_Host *host)
{
int i, k;
+#ifdef CONFIG_QL_ISP_A64
+ u_long queue_addr;
+ u_short param[8];
+#else
u_int queue_addr;
u_short param[6];
+#endif
u_short isp_cfg1, hwrev;
unsigned long flags;
struct isp1020_hostdata *hostdata =
@@ -1753,13 +1835,20 @@
}
queue_addr = hostdata->res_dma;
-
+#ifdef CONFIG_QL_ISP_A64
+ param[0] = MBOX_CMD_INIT_RESPONSE_QUEUE_64;
+#else
param[0] = MBOX_INIT_RES_QUEUE;
+#endif
param[1] = RES_QUEUE_LEN + 1;
param[2] = (u_short) (queue_addr >> 16);
param[3] = (u_short) (queue_addr & 0xffff);
param[4] = 0;
param[5] = 0;
+#ifdef CONFIG_QL_ISP_A64
+ param[6] = (u_short) (queue_addr >> 48);
+ param[7] = (u_short) (queue_addr >> 32);
+#endif
isp1020_mbox_command(host, param);
@@ -1770,13 +1859,22 @@
}
queue_addr = hostdata->req_dma;
-
+#ifdef CONFIG_QL_ISP_A64
+ param[0] = MBOX_CMD_INIT_REQUEST_QUEUE_64;
+#else
param[0] = MBOX_INIT_REQ_QUEUE;
+#endif
param[1] = QLOGICISP_REQ_QUEUE_LEN + 1;
param[2] = (u_short) (queue_addr >> 16);
param[3] = (u_short) (queue_addr & 0xffff);
param[4] = 0;
+#ifdef CONFIG_QL_ISP_A64
+ param[5] = 0;
+ param[6] = (u_short) (queue_addr >> 48);
+ param[7] = (u_short) (queue_addr >> 32);
+#endif
+
isp1020_mbox_command(host, param);
if (param[0] != MBOX_COMMAND_COMPLETE) {
@@ -1811,6 +1909,8 @@
printk("qlogicisp: mbox_command loop timeout #1\n");
switch(mbox_param[param[0]] >> 4) {
+ case 8: isp_outw(param[7], host, MBOX7);
+ case 7: isp_outw(param[6], host, MBOX6);
case 6: isp_outw(param[5], host, MBOX5);
case 5: isp_outw(param[4], host, MBOX4);
case 4: isp_outw(param[3], host, MBOX3);
@@ -1836,6 +1936,8 @@
printk("qlogicisp: mbox_command loop timeout #3\n");
switch(mbox_param[param[0]] & 0xf) {
+ case 8: param[7] = isp_inw(host, MBOX7);
+ case 7: param[6] = isp_inw(host, MBOX6);
case 6: param[5] = isp_inw(host, MBOX5);
case 5: param[4] = isp_inw(host, MBOX4);
case 4: param[3] = isp_inw(host, MBOX3);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)