Commit c83b4e61 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] gdth update from Intel

parent 8c8373b4
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Intel Corporation: Storage RAID Controllers * * Intel Corporation: Storage RAID Controllers *
* * * *
* gdth.c * * gdth.c *
* Copyright (C) 1995-02 ICP vortex, an Intel company, Achim Leubner * * Copyright (C) 1995-03 ICP vortex, an Intel company, Achim Leubner *
* <achim.leubner@intel.com> * * <achim.leubner@intel.com> *
* * * *
* Additions/Fixes: Boji Tony Kannanthanam * * Additions/Fixes: Boji Tony Kannanthanam *
...@@ -24,11 +24,17 @@ ...@@ -24,11 +24,17 @@
* along with this kernel; if not, write to the Free Software * * along with this kernel; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* * * *
* Tested with Linux 1.2.13, ..., 2.2.20, ..., 2.4.18 * * Tested with Linux 1.2.13, ..., 2.2.20, ..., 2.4.20 *
* * * *
* $Log: gdth.c,v $ * $Log: gdth.c,v $
* Revision 1.61 2002/10/03 09:35:22 boji * Revision 1.62 2003/02/27 15:01:59 achim
* Fixed SCREENSERVICE initialisation in SMP cases. * Dynamic DMA mapping implemented
* New (character device) IOCTL interface added
* Other controller related changes made
*
* Revision 1.61 2002/11/08 13:09:52 boji
* Added support for XSCALE based RAID Controllers
* Fixed SCREENSERVICE initialization in SMP cases
* Added checks for gdth_polling before GDTH_HA_LOCK * Added checks for gdth_polling before GDTH_HA_LOCK
* *
* Revision 1.60 2002/02/05 09:35:22 achim * Revision 1.60 2002/02/05 09:35:22 achim
...@@ -216,7 +222,7 @@ ...@@ -216,7 +222,7 @@
* *
* Revision 1.9 1997/09/04 10:07:25 achim * Revision 1.9 1997/09/04 10:07:25 achim
* IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ... * IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ...
* register_reboot_notifier() to get a notify on shutdown used * register_reboot_notifier() to get a notify on shutown used
* *
* Revision 1.8 1997/04/02 12:14:30 achim * Revision 1.8 1997/04/02 12:14:30 achim
* Version 1.00 (see gdth.h), tested with kernel 2.0.29 * Version 1.00 (see gdth.h), tested with kernel 2.0.29
...@@ -248,7 +254,7 @@ ...@@ -248,7 +254,7 @@
* Initial revision * Initial revision
* *
************************************************************************/ ************************************************************************/
#ident "$Id: gdth.c,v 1.60 2002/02/05 09:35:22 achim Exp $" #ident "$Id: gdth.c,v 1.62 2003/02/27 15:01:59 achim Exp $"
/* All GDT Disk Array Controllers are fully supported by this driver. /* All GDT Disk Array Controllers are fully supported by this driver.
* This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
...@@ -300,18 +306,21 @@ ...@@ -300,18 +306,21 @@
*/ */
/* The meaning of the Scsi_Pointer members in this driver is as follows: /* The meaning of the Scsi_Pointer members in this driver is as follows:
* ptr: Chaining * ptr: Chaining
* this_residual: Command priority * this_residual: Command priority
* buffer: Unused * buffer: phys. DMA sense buffer
* buffers_residual: Timeout value * dma_handle: phys. DMA buffer (kernel >= 2.4.0)
* Status: Command status (gdth_do_cmd()) * buffers_residual: Timeout value
* Message: Additional info (gdth_do_cmd()) * Status: Command status (gdth_do_cmd()), DMA mem. mappings
* have_data_in: Flag for gdth_wait_completion() * Message: Additional info (gdth_do_cmd()), DMA direction
* sent_command: Opcode special command * have_data_in: Flag for gdth_wait_completion()
* phase: Service/parameter/return code special command * sent_command: Opcode special command
* phase: Service/parameter/return code special command
*/ */
#error Please convert me to Documentation/DMA-mapping.txt /* default: activate /proc and character device IOCTL interface */
#define GDTH_IOCTL_PROC
#define GDTH_IOCTL_CHRDEV
#include <linux/module.h> #include <linux/module.h>
...@@ -324,6 +333,7 @@ ...@@ -324,6 +333,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/time.h> #include <linux/time.h>
...@@ -340,6 +350,7 @@ ...@@ -340,6 +350,7 @@
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/uaccess.h>
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020322
#include <linux/spinlock.h> #include <linux/spinlock.h>
#elif LINUX_VERSION_CODE >= 0x02015F #elif LINUX_VERSION_CODE >= 0x02015F
...@@ -353,6 +364,9 @@ ...@@ -353,6 +364,9 @@
#endif #endif
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#if LINUX_VERSION_CODE < 0x020503
#include "sd.h"
#endif
#include "gdth.h" #include "gdth.h"
...@@ -378,7 +392,8 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application, ...@@ -378,7 +392,8 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application,
gdth_evt_str *estr); gdth_evt_str *estr);
static void gdth_clear_events(void); static void gdth_clear_events(void);
static void gdth_copy_internal_data(Scsi_Cmnd *scp,char *buffer,ushort count); static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
char *buffer,ushort count);
static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp);
static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive);
...@@ -408,6 +423,13 @@ static void gdth_munmap(void *addr); ...@@ -408,6 +423,13 @@ static void gdth_munmap(void *addr);
static const char *gdth_ctr_name(int hanum); static const char *gdth_ctr_name(int hanum);
#ifdef GDTH_IOCTL_CHRDEV
static int gdth_open(struct inode *inode, struct file *filep);
static int gdth_close(struct inode *inode, struct file *filep);
static int gdth_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg);
#endif
#if LINUX_VERSION_CODE >= 0x010300 #if LINUX_VERSION_CODE >= 0x010300
static void gdth_flush(int hanum); static void gdth_flush(int hanum);
#if LINUX_VERSION_CODE >= 0x020100 #if LINUX_VERSION_CODE >= 0x020100
...@@ -604,6 +626,9 @@ static unchar gdth_write_through = FALSE; /* write through */ ...@@ -604,6 +626,9 @@ static unchar gdth_write_through = FALSE; /* write through */
static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */
static int elastidx; static int elastidx;
static int eoldidx; static int eoldidx;
#ifdef GDTH_IOCTL_CHRDEV
static int major;
#endif
#define DIN 1 /* IN data direction */ #define DIN 1 /* IN data direction */
#define DOU 2 /* OUT data direction */ #define DOU 2 /* OUT data direction */
...@@ -641,24 +666,35 @@ static unchar gdth_direction_tab[0x100] = { ...@@ -641,24 +666,35 @@ static unchar gdth_direction_tab[0x100] = {
#define __init #define __init
#endif #endif
#if LINUX_VERSION_CODE >= 0x02015F #if LINUX_VERSION_CODE >= 0x020503
#define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock)
#define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags)
#define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags)
#define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags)
#define GDTH_UNLOCK_SCSI_DONE(dev, flags) spin_unlock_irqrestore(dev->host_lock,flags)
#define GDTH_LOCK_SCSI_DOCMD(dev) spin_lock_irq(dev->host_lock)
#define GDTH_UNLOCK_SCSI_DOCMD(dev) spin_unlock_irq(dev->host_lock)
#elif LINUX_VERSION_CODE >= 0x02015F
#define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock) #define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock)
#define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags) #define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags)
#define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags) #define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags)
#define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags) #define GDTH_LOCK_SCSI_DONE(flags) spin_lock_irqsave(&io_request_lock,flags)
#define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(dev->host_lock,flags) #define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(&io_request_lock,flags)
#define GDTH_LOCK_SCSI_DOCMD(dev) spin_lock_irq(dev->host_lock) #define GDTH_LOCK_SCSI_DOCMD() spin_lock_irq(&io_request_lock)
#define GDTH_UNLOCK_SCSI_DOCMD(dev) spin_unlock_irq(dev->host_lock) #define GDTH_UNLOCK_SCSI_DOCMD() spin_unlock_irq(&io_request_lock)
#else #else
#define GDTH_INIT_LOCK_HA(ha) do {} while (0) #define GDTH_INIT_LOCK_HA(ha) do {} while (0)
#define GDTH_LOCK_HA(ha,flags) do {save_flags(flags); cli();} while (0) #define GDTH_LOCK_HA(ha,flags) do {save_flags(flags); cli();} while (0)
#define GDTH_UNLOCK_HA(ha,flags) do {restore_flags(flags);} while (0) #define GDTH_UNLOCK_HA(ha,flags) do {restore_flags(flags);} while (0)
#define GDTH_LOCK_SCSI_DONE(dev, flags) do {} while (0) #define GDTH_LOCK_SCSI_DONE(flags) do {} while (0)
#define GDTH_UNLOCK_SCSI_DONE(dev, flags) do {} while (0) #define GDTH_UNLOCK_SCSI_DONE(flags) do {} while (0)
#define GDTH_LOCK_SCSI_DOCMD(dev) do {} while (0) #define GDTH_LOCK_SCSI_DOCMD() do {} while (0)
#define GDTH_UNLOCK_SCSI_DOCMD(dev) do {} while (0) #define GDTH_UNLOCK_SCSI_DOCMD() do {} while (0)
#endif #endif
/* LILO and modprobe/insmod parameters */ /* LILO and modprobe/insmod parameters */
...@@ -702,10 +738,21 @@ MODULE_PARM(rescan, "i"); ...@@ -702,10 +738,21 @@ MODULE_PARM(rescan, "i");
MODULE_PARM(virt_ctr, "i"); MODULE_PARM(virt_ctr, "i");
MODULE_PARM(shared_access, "i"); MODULE_PARM(shared_access, "i");
MODULE_AUTHOR("Achim Leubner"); MODULE_AUTHOR("Achim Leubner");
#endif
#if LINUX_VERSION_CODE >= 0x02040B
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#endif #endif
#endif #endif
#ifdef GDTH_IOCTL_CHRDEV
/* ioctl interface */
static struct file_operations gdth_fops = {
ioctl:gdth_ioctl,
open:gdth_open,
release:gdth_close,
};
#endif
/* /proc support */ /* /proc support */
#if LINUX_VERSION_CODE >= 0x010300 #if LINUX_VERSION_CODE >= 0x010300
#include <linux/stat.h> #include <linux/stat.h>
...@@ -813,6 +860,8 @@ GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr)) ...@@ -813,6 +860,8 @@ GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
PCI_DEVICE_ID_VORTEX_GDTNEWRX); PCI_DEVICE_ID_VORTEX_GDTNEWRX);
gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL, gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_SRC); PCI_DEVICE_ID_INTEL_SRC);
gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_SRC_XSCALE);
return cnt; return cnt;
} }
...@@ -820,10 +869,11 @@ GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr)) ...@@ -820,10 +869,11 @@ GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
/* Vortex only makes RAID controllers. /* Vortex only makes RAID controllers.
* We do not really want to specify all 550 ids here, so wildcard match. * We do not really want to specify all 550 ids here, so wildcard match.
*/ */
static struct pci_device_id gdthtable[] = { static struct pci_device_id gdthtable[] __devinitdata = {
{PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID }, {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
{PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID }, {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID},
{0} {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID},
{0}
}; };
MODULE_DEVICE_TABLE(pci,gdthtable); MODULE_DEVICE_TABLE(pci,gdthtable);
#endif #endif
...@@ -1235,6 +1285,9 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)) ...@@ -1235,6 +1285,9 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha))
ha->stype = (ulong32)pcistr->device_id; ha->stype = (ulong32)pcistr->device_id;
ha->subdevice_id = pcistr->subdevice_id; ha->subdevice_id = pcistr->subdevice_id;
ha->irq = pcistr->irq; ha->irq = pcistr->irq;
#if LINUX_VERSION_CODE >= 0x20400
ha->pdev = pcistr->pdev;
#endif
if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */
TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
...@@ -1511,6 +1564,11 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)) ...@@ -1511,6 +1564,11 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha))
PCI_ROM_ADDRESS, rom_addr); PCI_ROM_ADDRESS, rom_addr);
#endif #endif
/* Ensure that it is safe to access the non HW portions of DPMEM.
* Aditional check needed for Xscale based RAID controllers */
while( ((int)gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg) ) & 3 )
gdth_delay(1);
/* check and reset interface area */ /* check and reset interface area */
dp6m_ptr = (gdt6m_dpram_str *)ha->brd; dp6m_ptr = (gdt6m_dpram_str *)ha->brd;
gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u);
...@@ -1840,7 +1898,7 @@ static void gdth_release_event(int hanum) ...@@ -1840,7 +1898,7 @@ static void gdth_release_event(int hanum)
if (ha->type == GDT_EISA) { if (ha->type == GDT_EISA) {
if (ha->pccb->OpCode == GDT_INIT) /* store DMA buffer */ if (ha->pccb->OpCode == GDT_INIT) /* store DMA buffer */
outl(virt_to_bus(ha->pccb), ha->bmic + MAILBOXREG); outl(ha->ccb_phys, ha->bmic + MAILBOXREG);
outb(ha->pccb->Service, ha->bmic + LDOORREG); outb(ha->pccb->Service, ha->bmic + LDOORREG);
} else if (ha->type == GDT_ISA) { } else if (ha->type == GDT_ISA) {
gdth_writeb(0, &((gdt2_dpram_str *)ha->brd)->io.event); gdth_writeb(0, &((gdt2_dpram_str *)ha->brd)->io.event);
...@@ -1916,7 +1974,7 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, ...@@ -1916,7 +1974,7 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1,
cmd_ptr->u.ioctl.subfunc = p1; cmd_ptr->u.ioctl.subfunc = p1;
cmd_ptr->u.ioctl.channel = p2; cmd_ptr->u.ioctl.channel = p2;
cmd_ptr->u.ioctl.param_size = (ushort)p3; cmd_ptr->u.ioctl.param_size = (ushort)p3;
cmd_ptr->u.ioctl.p_param = virt_to_bus(ha->pscratch); cmd_ptr->u.ioctl.p_param = ha->scratch_phys;
} else { } else {
cmd_ptr->u.cache.DeviceNo = (ushort)p1; cmd_ptr->u.cache.DeviceNo = (ushort)p1;
cmd_ptr->u.cache.BlockNo = p2; cmd_ptr->u.cache.BlockNo = p2;
...@@ -1965,6 +2023,8 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum)) ...@@ -1965,6 +2023,8 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
gdth_raw_iochan_str *iocr; gdth_raw_iochan_str *iocr;
gdth_arcdl_str *alst; gdth_arcdl_str *alst;
gdth_alist_str *alst2; gdth_alist_str *alst2;
gdth_oem_str_ioctl *oemstr;
#ifdef GDTH_RTC #ifdef GDTH_RTC
unchar rtc[12]; unchar rtc[12];
ulong flags; ulong flags;
...@@ -2233,6 +2293,27 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum)) ...@@ -2233,6 +2293,27 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
} }
} }
/* Determine OEM string using IOCTL */
oemstr = (gdth_oem_str_ioctl *)ha->pscratch;
oemstr->params.ctl_version = 0x01;
oemstr->params.buffer_size = sizeof(oemstr->text);
if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,
CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL,
sizeof(gdth_oem_str_ioctl))) {
TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n"));
printk("GDT CTR%d Vendor: %s\n",hanum,oemstr->text.oem_company_name);
/* Save the Host Drive inquiry data */
strncpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id,7);
ha->oem_name[7] = '\0';
} else {
/* Old method, based on PCI ID */
TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n"));
if (ha->oem_id == OEM_ID_INTEL)
strcpy(ha->oem_name,"Intel ");
else
strcpy(ha->oem_name,"ICP ");
}
/* scanning for host drives */ /* scanning for host drives */
for (i = 0; i < cdev_cnt; ++i) for (i = 0; i < cdev_cnt; ++i)
gdth_analyse_hdrive(hanum,i); gdth_analyse_hdrive(hanum,i);
...@@ -2313,8 +2394,13 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) ...@@ -2313,8 +2394,13 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority)
GDTH_LOCK_HA(ha, flags); GDTH_LOCK_HA(ha, flags);
scp->SCp.this_residual = (int)priority; scp->SCp.this_residual = (int)priority;
#if LINUX_VERSION_CODE >= 0x02053C
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
t = scp->device->id; t = scp->device->id;
#else
b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
t = scp->target;
#endif
#if LINUX_VERSION_CODE >= 0x010300 #if LINUX_VERSION_CODE >= 0x010300
if (priority >= DEFAULT_PRI) { if (priority >= DEFAULT_PRI) {
if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
...@@ -2357,7 +2443,7 @@ static void gdth_next(int hanum) ...@@ -2357,7 +2443,7 @@ static void gdth_next(int hanum)
register gdth_ha_str *ha; register gdth_ha_str *ha;
register Scsi_Cmnd *pscp; register Scsi_Cmnd *pscp;
register Scsi_Cmnd *nscp; register Scsi_Cmnd *nscp;
unchar b, t, firsttime; unchar b, t, l, firsttime;
unchar this_cmd, next_cmd; unchar this_cmd, next_cmd;
ulong flags = 0; ulong flags = 0;
int cmd_index; int cmd_index;
...@@ -2365,7 +2451,7 @@ static void gdth_next(int hanum) ...@@ -2365,7 +2451,7 @@ static void gdth_next(int hanum)
TRACE(("gdth_next() hanum %d\n",hanum)); TRACE(("gdth_next() hanum %d\n",hanum));
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
if (!gdth_polling) if (!gdth_polling)
GDTH_LOCK_HA(ha, flags); GDTH_LOCK_HA(ha, flags);
ha->cmd_cnt = ha->cmd_offs_dpmem = 0; ha->cmd_cnt = ha->cmd_offs_dpmem = 0;
this_cmd = firsttime = TRUE; this_cmd = firsttime = TRUE;
...@@ -2375,8 +2461,15 @@ static void gdth_next(int hanum) ...@@ -2375,8 +2461,15 @@ static void gdth_next(int hanum)
for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) {
if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr)
pscp = (Scsi_Cmnd *)pscp->SCp.ptr; pscp = (Scsi_Cmnd *)pscp->SCp.ptr;
#if LINUX_VERSION_CODE >= 0x02053C
b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel; b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel;
t = nscp->device->id; t = nscp->device->id;
l = nscp->device->lun;
#else
b = virt_ctr ? NUMDATA(nscp->host)->busnum : nscp->channel;
t = nscp->target;
l = nscp->lun;
#endif
if (nscp->SCp.this_residual >= DEFAULT_PRI) { if (nscp->SCp.this_residual >= DEFAULT_PRI) {
if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
(b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock))
...@@ -2404,16 +2497,16 @@ static void gdth_next(int hanum) ...@@ -2404,16 +2497,16 @@ static void gdth_next(int hanum)
nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */
if (nscp->cmnd[0] == TEST_UNIT_READY) { if (nscp->cmnd[0] == TEST_UNIT_READY) {
TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n",
b, t, nscp->lun)); b, t, l));
/* TEST_UNIT_READY -> set scan mode */ /* TEST_UNIT_READY -> set scan mode */
if ((ha->scan_mode & 0x0f) == 0) { if ((ha->scan_mode & 0x0f) == 0) {
if (b == 0 && t == 0 && nscp->device->lun == 0) { if (b == 0 && t == 0 && l == 0) {
ha->scan_mode |= 1; ha->scan_mode |= 1;
TRACE2(("Scan mode: 0x%x\n", ha->scan_mode)); TRACE2(("Scan mode: 0x%x\n", ha->scan_mode));
} }
} else if ((ha->scan_mode & 0x0f) == 1) { } else if ((ha->scan_mode & 0x0f) == 1) {
if (b == 0 && ((t == 0 && nscp->device->lun == 1) || if (b == 0 && ((t == 0 && l == 1) ||
(t == 1 && nscp->device->lun == 0))) { (t == 1 && l == 0))) {
nscp->SCp.sent_command = GDT_SCAN_START; nscp->SCp.sent_command = GDT_SCAN_START;
nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8)
| SCSIRAWSERVICE; | SCSIRAWSERVICE;
...@@ -2465,7 +2558,7 @@ static void gdth_next(int hanum) ...@@ -2465,7 +2558,7 @@ static void gdth_next(int hanum)
/* io_request_lock already active ! */ /* io_request_lock already active ! */
nscp->scsi_done(nscp); nscp->scsi_done(nscp);
if (!gdth_polling) if (!gdth_polling)
GDTH_LOCK_HA(ha,flags); GDTH_LOCK_HA(ha,flags);
} }
} }
} else } else
...@@ -2483,19 +2576,19 @@ static void gdth_next(int hanum) ...@@ -2483,19 +2576,19 @@ static void gdth_next(int hanum)
this_cmd = FALSE; this_cmd = FALSE;
else else
ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; ha->raw[BUS_L2P(ha,b)].io_cnt[t]++;
} else if (t >= MAX_HDRIVES || !ha->hdr[t].present || nscp->device->lun != 0) { } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || l != 0) {
TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n",
nscp->cmnd[0], b, t, nscp->lun)); nscp->cmnd[0], b, t, l));
nscp->result = DID_BAD_TARGET << 16; nscp->result = DID_BAD_TARGET << 16;
if (!nscp->SCp.have_data_in) if (!nscp->SCp.have_data_in)
nscp->SCp.have_data_in++; nscp->SCp.have_data_in++;
else { else {
if (!gdth_polling) if (!gdth_polling)
GDTH_UNLOCK_HA(ha,flags); GDTH_UNLOCK_HA(ha,flags);
/* io_request_lock already active ! */ /* io_request_lock already active ! */
nscp->scsi_done(nscp); nscp->scsi_done(nscp);
if (!gdth_polling) if (!gdth_polling)
GDTH_LOCK_HA(ha,flags); GDTH_LOCK_HA(ha,flags);
} }
} else { } else {
switch (nscp->cmnd[0]) { switch (nscp->cmnd[0]) {
...@@ -2521,20 +2614,20 @@ static void gdth_next(int hanum) ...@@ -2521,20 +2614,20 @@ static void gdth_next(int hanum)
if (!nscp->SCp.have_data_in) if (!nscp->SCp.have_data_in)
nscp->SCp.have_data_in++; nscp->SCp.have_data_in++;
else { else {
if (!gdth_polling) if (!gdth_polling)
GDTH_UNLOCK_HA(ha,flags); GDTH_UNLOCK_HA(ha,flags);
/* io_request_lock already active ! */ /* io_request_lock already active ! */
nscp->scsi_done(nscp); nscp->scsi_done(nscp);
if (!gdth_polling) if (!gdth_polling)
GDTH_LOCK_HA(ha,flags); GDTH_LOCK_HA(ha,flags);
} }
} else if (gdth_internal_cache_cmd(hanum,nscp)) { } else if (gdth_internal_cache_cmd(hanum,nscp)) {
if (!gdth_polling) if (!gdth_polling)
GDTH_UNLOCK_HA(ha,flags); GDTH_UNLOCK_HA(ha,flags);
/* io_request_lock already active ! */ /* io_request_lock already active ! */
nscp->scsi_done(nscp); nscp->scsi_done(nscp);
if (!gdth_polling) if (!gdth_polling)
GDTH_LOCK_HA(ha,flags); GDTH_LOCK_HA(ha,flags);
} }
break; break;
...@@ -2549,12 +2642,12 @@ static void gdth_next(int hanum) ...@@ -2549,12 +2642,12 @@ static void gdth_next(int hanum)
if (!nscp->SCp.have_data_in) if (!nscp->SCp.have_data_in)
nscp->SCp.have_data_in++; nscp->SCp.have_data_in++;
else { else {
if (!gdth_polling) if (!gdth_polling)
GDTH_UNLOCK_HA(ha,flags); GDTH_UNLOCK_HA(ha,flags);
/* io_request_lock already active ! */ /* io_request_lock already active ! */
nscp->scsi_done(nscp); nscp->scsi_done(nscp);
if (!gdth_polling) if (!gdth_polling)
GDTH_LOCK_HA(ha,flags); GDTH_LOCK_HA(ha,flags);
} }
} else { } else {
nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0;
...@@ -2589,12 +2682,12 @@ static void gdth_next(int hanum) ...@@ -2589,12 +2682,12 @@ static void gdth_next(int hanum)
if (!nscp->SCp.have_data_in) if (!nscp->SCp.have_data_in)
nscp->SCp.have_data_in++; nscp->SCp.have_data_in++;
else { else {
if (!gdth_polling) if (!gdth_polling)
GDTH_UNLOCK_HA(ha,flags); GDTH_UNLOCK_HA(ha,flags);
/* io_request_lock already active ! */ /* io_request_lock already active ! */
nscp->scsi_done(nscp); nscp->scsi_done(nscp);
if (!gdth_polling) if (!gdth_polling)
GDTH_LOCK_HA(ha,flags); GDTH_LOCK_HA(ha,flags);
} }
} else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
this_cmd = FALSE; this_cmd = FALSE;
...@@ -2611,11 +2704,11 @@ static void gdth_next(int hanum) ...@@ -2611,11 +2704,11 @@ static void gdth_next(int hanum)
nscp->SCp.have_data_in++; nscp->SCp.have_data_in++;
else { else {
if (!gdth_polling) if (!gdth_polling)
GDTH_UNLOCK_HA(ha,flags); GDTH_UNLOCK_HA(ha,flags);
/* io_request_lock already active ! */ /* io_request_lock already active ! */
nscp->scsi_done(nscp); nscp->scsi_done(nscp);
if (!gdth_polling) if (!gdth_polling)
GDTH_LOCK_HA(ha,flags); GDTH_LOCK_HA(ha,flags);
} }
break; break;
} }
...@@ -2636,7 +2729,7 @@ static void gdth_next(int hanum) ...@@ -2636,7 +2729,7 @@ static void gdth_next(int hanum)
} }
if (!gdth_polling) if (!gdth_polling)
GDTH_UNLOCK_HA(ha, flags); GDTH_UNLOCK_HA(ha, flags);
if (gdth_polling && ha->cmd_cnt > 0) { if (gdth_polling && ha->cmd_cnt > 0) {
if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT)) if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT))
...@@ -2645,27 +2738,54 @@ static void gdth_next(int hanum) ...@@ -2645,27 +2738,54 @@ static void gdth_next(int hanum)
} }
} }
static void gdth_copy_internal_data(Scsi_Cmnd *scp,char *buffer,ushort count) static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
char *buffer,ushort count)
{ {
ushort cpcount,i; ushort cpcount,i;
ushort cpsum,cpnow; ushort cpsum,cpnow;
struct scatterlist *sl; struct scatterlist *sl;
gdth_ha_str *ha;
int sgcnt;
char *address;
cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen; cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
ha = HADATA(gdth_ctr_tab[hanum]);
if (scp->use_sg) { if (scp->use_sg) {
sl = (struct scatterlist *)scp->request_buffer; sl = (struct scatterlist *)scp->request_buffer;
for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) { #if LINUX_VERSION_CODE >= 0x020400
cpnow = (ushort)sl->length; sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,PCI_DMA_FROMDEVICE);
for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
cpnow = (ushort)sg_dma_len(sl);
TRACE(("copy_internal() now %d sum %d count %d %d\n", TRACE(("copy_internal() now %d sum %d count %d %d\n",
cpnow,cpsum,cpcount,(ushort)scp->bufflen)); cpnow,cpsum,cpcount,(ushort)scp->bufflen));
if (cpsum+cpnow > cpcount) if (cpsum+cpnow > cpcount)
cpnow = cpcount - cpsum; cpnow = cpcount - cpsum;
cpsum += cpnow; cpsum += cpnow;
memcpy((char*)sl->address,buffer,cpnow); address = (char *)phys_to_virt(sg_dma_address(sl));
memcpy(address,buffer,cpnow);
if (cpsum == cpcount)
break;
buffer += cpnow;
}
pci_unmap_sg(ha->pdev,scp->request_buffer,
scp->use_sg,PCI_DMA_FROMDEVICE);
#else
sgcnt = scp->use_sg;
for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
cpnow = (ushort)sl->length;
TRACE(("copy_internal() now %d sum %d count %d %d\n",
cpnow,cpsum,cpcount,(ushort)scp->bufflen));
if (cpsum+cpnow > cpcount)
cpnow = cpcount - cpsum;
cpsum += cpnow;
address = (char *)sl->address;
memcpy(address,buffer,cpnow);
if (cpsum == cpcount) if (cpsum == cpcount)
break; break;
buffer += cpnow; buffer += cpnow;
} }
#endif
} else { } else {
TRACE(("copy_internal() count %d\n",cpcount)); TRACE(("copy_internal() count %d\n",cpcount));
memcpy((char*)scp->request_buffer,buffer,cpcount); memcpy((char*)scp->request_buffer,buffer,cpcount);
...@@ -2682,7 +2802,11 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) ...@@ -2682,7 +2802,11 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
gdth_modep_data mpd; gdth_modep_data mpd;
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
#if LINUX_VERSION_CODE >= 0x02053C
t = scp->device->id; t = scp->device->id;
#else
t = scp->target;
#endif
TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n",
scp->cmnd[0],t)); scp->cmnd[0],t));
...@@ -2706,13 +2830,10 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) ...@@ -2706,13 +2830,10 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
inq.version = 2; inq.version = 2;
inq.resp_aenc = 2; inq.resp_aenc = 2;
inq.add_length= 32; inq.add_length= 32;
if (ha->oem_id == OEM_ID_INTEL) strcpy(inq.vendor,ha->oem_name);
strcpy(inq.vendor,"Intel ");
else
strcpy(inq.vendor,"ICP ");
sprintf(inq.product,"Host Drive #%02d",t); sprintf(inq.product,"Host Drive #%02d",t);
strcpy(inq.revision," "); strcpy(inq.revision," ");
gdth_copy_internal_data(scp,(char*)&inq,sizeof(gdth_inq_data)); gdth_copy_internal_data(hanum,scp,(char*)&inq,sizeof(gdth_inq_data));
break; break;
case REQUEST_SENSE: case REQUEST_SENSE:
...@@ -2722,7 +2843,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) ...@@ -2722,7 +2843,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
sd.key = NO_SENSE; sd.key = NO_SENSE;
sd.info = 0; sd.info = 0;
sd.add_length= 0; sd.add_length= 0;
gdth_copy_internal_data(scp,(char*)&sd,sizeof(gdth_sense_data)); gdth_copy_internal_data(hanum,scp,(char*)&sd,sizeof(gdth_sense_data));
break; break;
case MODE_SENSE: case MODE_SENSE:
...@@ -2734,14 +2855,14 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) ...@@ -2734,14 +2855,14 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16;
mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8;
mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff);
gdth_copy_internal_data(scp,(char*)&mpd,sizeof(gdth_modep_data)); gdth_copy_internal_data(hanum,scp,(char*)&mpd,sizeof(gdth_modep_data));
break; break;
case READ_CAPACITY: case READ_CAPACITY:
TRACE2(("Read capacity hdrive %d\n",t)); TRACE2(("Read capacity hdrive %d\n",t));
rdc.last_block_no = ntohl(ha->hdr[t].size-1); rdc.last_block_no = ntohl(ha->hdr[t].size-1);
rdc.block_length = ntohl(SECTOR_SIZE); rdc.block_length = ntohl(SECTOR_SIZE);
gdth_copy_internal_data(scp,(char*)&rdc,sizeof(gdth_rdcap_data)); gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data));
break; break;
default: default:
...@@ -2766,8 +2887,8 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) ...@@ -2766,8 +2887,8 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
register gdth_cmd_str *cmdp; register gdth_cmd_str *cmdp;
struct scatterlist *sl; struct scatterlist *sl;
ushort i, cnt; ushort i, cnt;
ulong32 no; ulong32 no, phys_addr;
int cmd_index, read_write; int cmd_index, read_write, sgcnt;
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
cmdp = ha->pccb; cmdp = ha->pccb;
...@@ -2789,7 +2910,7 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) ...@@ -2789,7 +2910,7 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
gdth_set_sema0(hanum); gdth_set_sema0(hanum);
/* fill command */ /* fill command */
read_write = FALSE; read_write = 0;
if (scp->SCp.sent_command != -1) if (scp->SCp.sent_command != -1)
cmdp->OpCode = scp->SCp.sent_command; /* special cache cmd. */ cmdp->OpCode = scp->SCp.sent_command; /* special cache cmd. */
else if (scp->cmnd[0] == RESERVE) else if (scp->cmnd[0] == RESERVE)
...@@ -2803,15 +2924,16 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) ...@@ -2803,15 +2924,16 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
cmdp->OpCode = GDT_UNMOUNT; cmdp->OpCode = GDT_UNMOUNT;
else else
cmdp->OpCode = GDT_FLUSH; cmdp->OpCode = GDT_FLUSH;
} else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10) { } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10 ||
read_write = TRUE; scp->cmnd[0] == WRITE_12) {
read_write = 1;
if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) &&
(ha->cache_feat & GDT_WR_THROUGH))) (ha->cache_feat & GDT_WR_THROUGH)))
cmdp->OpCode = GDT_WRITE_THR; cmdp->OpCode = GDT_WRITE_THR;
else else
cmdp->OpCode = GDT_WRITE; cmdp->OpCode = GDT_WRITE;
} else { } else {
read_write = TRUE; read_write = 2;
cmdp->OpCode = GDT_READ; cmdp->OpCode = GDT_READ;
} }
...@@ -2835,10 +2957,22 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) ...@@ -2835,10 +2957,22 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
if (scp->use_sg) { if (scp->use_sg) {
cmdp->u.cache.DestAddr= 0xffffffff; cmdp->u.cache.DestAddr= 0xffffffff;
sl = (struct scatterlist *)scp->request_buffer; sl = (struct scatterlist *)scp->request_buffer;
for (i=0; i<scp->use_sg; ++i,++sl) { sgcnt = scp->use_sg;
#if LINUX_VERSION_CODE >= 0x020400
scp->SCp.Status = GDTH_MAP_SG;
scp->SCp.Message = (read_write == 1 ?
PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message);
for (i=0; i<sgcnt; ++i,++sl) {
cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl);
cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl);
}
#else
for (i=0; i<sgcnt; ++i,++sl) {
cmdp->u.cache.sg_lst[i].sg_ptr = virt_to_bus(sl->address); cmdp->u.cache.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
cmdp->u.cache.sg_lst[i].sg_len = (ulong32)sl->length; cmdp->u.cache.sg_lst[i].sg_len = (ulong32)sl->length;
} }
#endif
cmdp->u.cache.sg_canz = (ulong32)i; cmdp->u.cache.sg_canz = (ulong32)i;
#ifdef GDTH_STATISTICS #ifdef GDTH_STATISTICS
...@@ -2850,15 +2984,24 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) ...@@ -2850,15 +2984,24 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
if (i<GDTH_MAXSG) if (i<GDTH_MAXSG)
cmdp->u.cache.sg_lst[i].sg_len = 0; cmdp->u.cache.sg_lst[i].sg_len = 0;
} else { } else {
#if LINUX_VERSION_CODE >= 0x020400
scp->SCp.Status = GDTH_MAP_SINGLE;
scp->SCp.Message = (read_write == 1 ?
PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
phys_addr = pci_map_single(ha->pdev,scp->request_buffer,
scp->request_bufflen,scp->SCp.Message);
scp->SCp.dma_handle = phys_addr;
#else
phys_addr = virt_to_bus(scp->request_buffer);
#endif
if (ha->cache_feat & SCATTER_GATHER) { if (ha->cache_feat & SCATTER_GATHER) {
cmdp->u.cache.DestAddr = 0xffffffff; cmdp->u.cache.DestAddr = 0xffffffff;
cmdp->u.cache.sg_canz = 1; cmdp->u.cache.sg_canz = 1;
cmdp->u.cache.sg_lst[0].sg_ptr = cmdp->u.cache.sg_lst[0].sg_ptr = phys_addr;
virt_to_bus(scp->request_buffer);
cmdp->u.cache.sg_lst[0].sg_len = scp->request_bufflen; cmdp->u.cache.sg_lst[0].sg_len = scp->request_bufflen;
cmdp->u.cache.sg_lst[1].sg_len = 0; cmdp->u.cache.sg_lst[1].sg_len = 0;
} else { } else {
cmdp->u.cache.DestAddr = virt_to_bus(scp->request_buffer); cmdp->u.cache.DestAddr = phys_addr;
cmdp->u.cache.sg_canz= 0; cmdp->u.cache.sg_canz= 0;
} }
} }
...@@ -2896,12 +3039,18 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) ...@@ -2896,12 +3039,18 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
register gdth_cmd_str *cmdp; register gdth_cmd_str *cmdp;
struct scatterlist *sl; struct scatterlist *sl;
ushort i; ushort i;
int cmd_index; ulong32 phys_addr, sense_paddr;
int cmd_index, sgcnt;
unchar t,l; unchar t,l;
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
#if LINUX_VERSION_CODE >= 0x02053C
t = scp->device->id; t = scp->device->id;
l = scp->device->lun; l = scp->device->lun;
#else
t = scp->target;
l = scp->lun;
#endif
cmdp = ha->pccb; cmdp = ha->pccb;
TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n", TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n",
scp->cmnd[0],b,t,l)); scp->cmnd[0],b,t,l));
...@@ -2931,6 +3080,13 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) ...@@ -2931,6 +3080,13 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
/* evaluate command size */ /* evaluate command size */
ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst); ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst);
} else { } else {
#if LINUX_VERSION_CODE >= 0x020400
sense_paddr = pci_map_single(ha->pdev,scp->sense_buffer,
16,PCI_DMA_FROMDEVICE);
scp->SCp.buffer = (struct scatterlist *)sense_paddr;
#else
sense_paddr = virt_to_bus(scp->sense_buffer);
#endif
cmdp->OpCode = GDT_WRITE; /* always */ cmdp->OpCode = GDT_WRITE; /* always */
cmdp->BoardNode = LOCALBOARD; cmdp->BoardNode = LOCALBOARD;
cmdp->u.raw.reserved = 0; cmdp->u.raw.reserved = 0;
...@@ -2944,7 +3100,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) ...@@ -2944,7 +3100,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
cmdp->u.raw.link_p = 0; cmdp->u.raw.link_p = 0;
cmdp->u.raw.sdlen = scp->request_bufflen; cmdp->u.raw.sdlen = scp->request_bufflen;
cmdp->u.raw.sense_len = 16; cmdp->u.raw.sense_len = 16;
cmdp->u.raw.sense_data = virt_to_bus(scp->sense_buffer); cmdp->u.raw.sense_data = sense_paddr;
cmdp->u.raw.direction = cmdp->u.raw.direction =
gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN; gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN;
memcpy(cmdp->u.raw.cmd,scp->cmnd,12); memcpy(cmdp->u.raw.cmd,scp->cmnd,12);
...@@ -2952,10 +3108,21 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) ...@@ -2952,10 +3108,21 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
if (scp->use_sg) { if (scp->use_sg) {
cmdp->u.raw.sdata = 0xffffffff; cmdp->u.raw.sdata = 0xffffffff;
sl = (struct scatterlist *)scp->request_buffer; sl = (struct scatterlist *)scp->request_buffer;
for (i=0; i<scp->use_sg; ++i,++sl) { sgcnt = scp->use_sg;
#if LINUX_VERSION_CODE >= 0x020400
scp->SCp.Status = GDTH_MAP_SG;
scp->SCp.Message = PCI_DMA_BIDIRECTIONAL;
sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message);
for (i=0; i<sgcnt; ++i,++sl) {
cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl);
cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl);
}
#else
for (i=0; i<sgcnt; ++i,++sl) {
cmdp->u.raw.sg_lst[i].sg_ptr = virt_to_bus(sl->address); cmdp->u.raw.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
cmdp->u.raw.sg_lst[i].sg_len = (ulong32)sl->length; cmdp->u.raw.sg_lst[i].sg_len = (ulong32)sl->length;
} }
#endif
cmdp->u.raw.sg_ranz = (ulong32)i; cmdp->u.raw.sg_ranz = (ulong32)i;
#ifdef GDTH_STATISTICS #ifdef GDTH_STATISTICS
...@@ -2967,14 +3134,23 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) ...@@ -2967,14 +3134,23 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
if (i<GDTH_MAXSG) if (i<GDTH_MAXSG)
cmdp->u.raw.sg_lst[i].sg_len = 0; cmdp->u.raw.sg_lst[i].sg_len = 0;
} else { } else {
#if LINUX_VERSION_CODE >= 0x020400
scp->SCp.Status = GDTH_MAP_SINGLE;
scp->SCp.Message = PCI_DMA_BIDIRECTIONAL;
phys_addr = pci_map_single(ha->pdev,scp->request_buffer,
scp->request_bufflen,scp->SCp.Message);
scp->SCp.dma_handle = phys_addr;
#else
phys_addr = virt_to_bus(scp->request_buffer);
#endif
if (ha->raw_feat & SCATTER_GATHER) { if (ha->raw_feat & SCATTER_GATHER) {
cmdp->u.raw.sdata = 0xffffffff; cmdp->u.raw.sdata = 0xffffffff;
cmdp->u.raw.sg_ranz= 1; cmdp->u.raw.sg_ranz= 1;
cmdp->u.raw.sg_lst[0].sg_ptr = virt_to_bus(scp->request_buffer); cmdp->u.raw.sg_lst[0].sg_ptr = phys_addr;
cmdp->u.raw.sg_lst[0].sg_len = scp->request_bufflen; cmdp->u.raw.sg_lst[0].sg_len = scp->request_bufflen;
cmdp->u.raw.sg_lst[1].sg_len = 0; cmdp->u.raw.sg_lst[1].sg_len = 0;
} else { } else {
cmdp->u.raw.sdata = virt_to_bus(scp->request_buffer); cmdp->u.raw.sdata = phys_addr;
cmdp->u.raw.sg_ranz= 0; cmdp->u.raw.sg_ranz= 0;
} }
} }
...@@ -3372,9 +3548,19 @@ static void gdth_interrupt(int irq,struct pt_regs *regs) ...@@ -3372,9 +3548,19 @@ static void gdth_interrupt(int irq,struct pt_regs *regs)
if (rval == 2) { if (rval == 2) {
gdth_putq(hanum,scp,scp->SCp.this_residual); gdth_putq(hanum,scp,scp->SCp.this_residual);
} else if (rval == 1) { } else if (rval == 1) {
#if LINUX_VERSION_CODE >= 0x02053C
GDTH_LOCK_SCSI_DONE(scp->device->host, flags); GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
scp->scsi_done(scp); scp->scsi_done(scp);
GDTH_UNLOCK_SCSI_DONE(scp->host,flags); GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
#elif LINUX_VERSION_CODE >= 0x020503
GDTH_LOCK_SCSI_DONE(scp->host, flags);
scp->scsi_done(scp);
GDTH_UNLOCK_SCSI_DONE(scp->host, flags);
#else
GDTH_LOCK_SCSI_DONE(flags);
scp->scsi_done(scp);
GDTH_UNLOCK_SCSI_DONE(flags);
#endif
} }
gdth_next(hanum); gdth_next(hanum);
} }
...@@ -3384,7 +3570,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3384,7 +3570,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
register gdth_ha_str *ha; register gdth_ha_str *ha;
gdth_msg_str *msg; gdth_msg_str *msg;
gdth_cmd_str *cmdp; gdth_cmd_str *cmdp;
unchar b; unchar b, t;
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
cmdp = ha->pccb; cmdp = ha->pccb;
...@@ -3413,7 +3599,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3413,7 +3599,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
cmdp->BoardNode = LOCALBOARD; cmdp->BoardNode = LOCALBOARD;
cmdp->u.screen.reserved = 0; cmdp->u.screen.reserved = 0;
cmdp->u.screen.su.msg.msg_handle= msg->msg_handle; cmdp->u.screen.su.msg.msg_handle= msg->msg_handle;
cmdp->u.screen.su.msg.msg_addr = virt_to_bus(msg); cmdp->u.screen.su.msg.msg_addr = ha->scratch_phys;
ha->scratch_busy = TRUE; ha->scratch_busy = TRUE;
ha->cmd_offs_dpmem = 0; ha->cmd_offs_dpmem = 0;
ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr)
...@@ -3448,7 +3634,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3448,7 +3634,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
cmdp->BoardNode = LOCALBOARD; cmdp->BoardNode = LOCALBOARD;
cmdp->u.screen.reserved = 0; cmdp->u.screen.reserved = 0;
cmdp->u.screen.su.msg.msg_handle= msg->msg_handle; cmdp->u.screen.su.msg.msg_handle= msg->msg_handle;
cmdp->u.screen.su.msg.msg_addr = virt_to_bus(msg); cmdp->u.screen.su.msg.msg_addr = ha->scratch_phys;
ha->scratch_busy = TRUE; ha->scratch_busy = TRUE;
ha->cmd_offs_dpmem = 0; ha->cmd_offs_dpmem = 0;
ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr)
...@@ -3461,11 +3647,35 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3461,11 +3647,35 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
printk("\n"); printk("\n");
} else { } else {
#if LINUX_VERSION_CODE >= 0x02053C
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
t = scp->device->id;
#else
b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
t = scp->target;
#endif
if (scp->SCp.sent_command == -1 && b != ha->virt_bus) { if (scp->SCp.sent_command == -1 && b != ha->virt_bus) {
ha->raw[BUS_L2P(ha,b)].io_cnt[scp->device->id]--; ha->raw[BUS_L2P(ha,b)].io_cnt[t]--;
} }
/* cache or raw service */ /* cache or raw service */
if (ha->status == S_BSY) {
TRACE2(("Controller busy -> retry !\n"));
if (scp->SCp.sent_command == GDT_MOUNT)
scp->SCp.sent_command = GDT_CLUST_INFO;
/* retry */
return 2;
}
#if LINUX_VERSION_CODE >= 0x020400
if (scp->SCp.Status == GDTH_MAP_SG)
pci_unmap_sg(ha->pdev,scp->request_buffer,
scp->use_sg,scp->SCp.Message);
else if (scp->SCp.Status == GDTH_MAP_SINGLE)
pci_unmap_single(ha->pdev,scp->SCp.dma_handle,
scp->request_bufflen,scp->SCp.Message);
if (scp->SCp.buffer)
pci_unmap_single(ha->pdev,(dma_addr_t)scp->SCp.buffer,
16,PCI_DMA_FROMDEVICE);
#endif
if (ha->status == S_OK) { if (ha->status == S_OK) {
scp->SCp.Status = S_OK; scp->SCp.Status = S_OK;
scp->SCp.Message = ha->info; scp->SCp.Message = ha->info;
...@@ -3474,12 +3684,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3474,12 +3684,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
scp->SCp.sent_command)); scp->SCp.sent_command));
/* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */
if (scp->SCp.sent_command == GDT_CLUST_INFO) { if (scp->SCp.sent_command == GDT_CLUST_INFO) {
ha->hdr[scp->device->id].cluster_type = (unchar)ha->info; ha->hdr[t].cluster_type = (unchar)ha->info;
if (!(ha->hdr[scp->device->id].cluster_type & if (!(ha->hdr[t].cluster_type &
CLUSTER_MOUNTED)) { CLUSTER_MOUNTED)) {
/* NOT MOUNTED -> MOUNT */ /* NOT MOUNTED -> MOUNT */
scp->SCp.sent_command = GDT_MOUNT; scp->SCp.sent_command = GDT_MOUNT;
if (ha->hdr[scp->device->id].cluster_type & if (ha->hdr[t].cluster_type &
CLUSTER_RESERVED) { CLUSTER_RESERVED) {
/* cluster drive RESERVED (on the other node) */ /* cluster drive RESERVED (on the other node) */
scp->SCp.phase = -2; /* reservation conflict */ scp->SCp.phase = -2; /* reservation conflict */
...@@ -3489,11 +3699,11 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3489,11 +3699,11 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
} }
} else { } else {
if (scp->SCp.sent_command == GDT_MOUNT) { if (scp->SCp.sent_command == GDT_MOUNT) {
ha->hdr[scp->device->id].cluster_type |= CLUSTER_MOUNTED; ha->hdr[t].cluster_type |= CLUSTER_MOUNTED;
ha->hdr[scp->device->id].media_changed = TRUE; ha->hdr[t].media_changed = TRUE;
} else if (scp->SCp.sent_command == GDT_UNMOUNT) { } else if (scp->SCp.sent_command == GDT_UNMOUNT) {
ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_MOUNTED; ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED;
ha->hdr[scp->device->id].media_changed = TRUE; ha->hdr[t].media_changed = TRUE;
} }
scp->SCp.sent_command = -1; scp->SCp.sent_command = -1;
} }
...@@ -3503,21 +3713,13 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3503,21 +3713,13 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
} else { } else {
/* RESERVE/RELEASE ? */ /* RESERVE/RELEASE ? */
if (scp->cmnd[0] == RESERVE) { if (scp->cmnd[0] == RESERVE) {
ha->hdr[scp->device->id].cluster_type |= CLUSTER_RESERVED; ha->hdr[t].cluster_type |= CLUSTER_RESERVED;
} else if (scp->cmnd[0] == RELEASE) { } else if (scp->cmnd[0] == RELEASE) {
ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_RESERVED; ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED;
} }
scp->result = DID_OK << 16; scp->result = DID_OK << 16;
scp->sense_buffer[0] = 0; scp->sense_buffer[0] = 0;
} }
} else if (ha->status == S_BSY) {
TRACE2(("Controller busy -> retry !\n"));
scp->SCp.Status = S_BSY;
scp->SCp.Message = ha->info;
if (scp->SCp.sent_command == GDT_MOUNT)
scp->SCp.sent_command = GDT_CLUST_INFO;
/* retry */
return 2;
} else { } else {
scp->SCp.Status = ha->status; scp->SCp.Status = ha->status;
scp->SCp.Message = ha->info; scp->SCp.Message = ha->info;
...@@ -3538,10 +3740,10 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3538,10 +3740,10 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
} else if (service == CACHESERVICE) { } else if (service == CACHESERVICE) {
if (ha->status == S_CACHE_UNKNOWN && if (ha->status == S_CACHE_UNKNOWN &&
(ha->hdr[scp->device->id].cluster_type & (ha->hdr[t].cluster_type &
CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) { CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) {
/* bus reset -> force GDT_CLUST_INFO */ /* bus reset -> force GDT_CLUST_INFO */
ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_RESERVED; ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED;
} }
memset((char*)scp->sense_buffer,0,16); memset((char*)scp->sense_buffer,0,16);
if (ha->status == (ushort)S_CACHE_RESERV) { if (ha->status == (ushort)S_CACHE_RESERV) {
...@@ -3560,7 +3762,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) ...@@ -3560,7 +3762,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
ha->dvr.eu.sync.service = service; ha->dvr.eu.sync.service = service;
ha->dvr.eu.sync.status = ha->status; ha->dvr.eu.sync.status = ha->status;
ha->dvr.eu.sync.info = ha->info; ha->dvr.eu.sync.info = ha->info;
ha->dvr.eu.sync.hostdrive = scp->device->id; ha->dvr.eu.sync.hostdrive = t;
if (ha->status >= 0x8000) if (ha->status >= 0x8000)
gdth_store_event(ha, ES_SYNC, 0, &ha->dvr); gdth_store_event(ha, ES_SYNC, 0, &ha->dvr);
else else
...@@ -3765,7 +3967,7 @@ static int gdth_async_event(int hanum) ...@@ -3765,7 +3967,7 @@ static int gdth_async_event(int hanum)
cmdp->BoardNode = LOCALBOARD; cmdp->BoardNode = LOCALBOARD;
cmdp->u.screen.reserved = 0; cmdp->u.screen.reserved = 0;
cmdp->u.screen.su.msg.msg_handle= MSG_INV_HANDLE; cmdp->u.screen.su.msg.msg_handle= MSG_INV_HANDLE;
cmdp->u.screen.su.msg.msg_addr = virt_to_bus(msg); cmdp->u.screen.su.msg.msg_addr = ha->scratch_phys;
ha->scratch_busy = TRUE; ha->scratch_busy = TRUE;
ha->cmd_offs_dpmem = 0; ha->cmd_offs_dpmem = 0;
ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr)
...@@ -4028,8 +4230,8 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4028,8 +4230,8 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
break; break;
if (gdth_search_isa(isa_bios)) { /* controller found */ if (gdth_search_isa(isa_bios)) { /* controller found */
shp = scsi_register(shtp,sizeof(gdth_ext_str)); shp = scsi_register(shtp,sizeof(gdth_ext_str));
if(shp == NULL) if (shp == NULL)
continue; continue;
ha = HADATA(shp); ha = HADATA(shp);
if (!gdth_init_isa(isa_bios,ha)) { if (!gdth_init_isa(isa_bios,ha)) {
...@@ -4076,11 +4278,15 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4076,11 +4278,15 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
NUMDATA(shp)->busnum= 0; NUMDATA(shp)->busnum= 0;
ha->pccb = CMDDATA(shp); ha->pccb = CMDDATA(shp);
#if LINUX_VERSION_CODE >= 0x020322 ha->ccb_phys = 0L;
ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, #if LINUX_VERSION_CODE >= 0x020400
GDTH_SCRATCH_ORD); ha->pdev = NULL;
ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
&ha->scratch_phys);
#else #else
ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
if (ha->pscratch)
ha->scratch_phys = virt_to_bus(ha->pscratch);
#endif #endif
ha->scratch_busy = FALSE; ha->scratch_busy = FALSE;
ha->req_first = NULL; ha->req_first = NULL;
...@@ -4095,12 +4301,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4095,12 +4301,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
printk("GDT-ISA: Error during device scan\n"); printk("GDT-ISA: Error during device scan\n");
--gdth_ctr_count; --gdth_ctr_count;
--gdth_ctr_vcount; --gdth_ctr_vcount;
if (ha->pscratch != NULL) if (ha->pscratch != NULL) {
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020400
free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD); pci_free_consistent(ha->pdev, GDTH_SCRATCH,
ha->pscratch, ha->scratch_phys);
#else #else
scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
#endif #endif
}
#if LINUX_VERSION_CODE >= 0x010346 #if LINUX_VERSION_CODE >= 0x010346
free_irq(ha->irq,ha); free_irq(ha->irq,ha);
#else #else
...@@ -4145,8 +4353,8 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4145,8 +4353,8 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
break; break;
if (gdth_search_eisa(eisa_slot)) { /* controller found */ if (gdth_search_eisa(eisa_slot)) { /* controller found */
shp = scsi_register(shtp,sizeof(gdth_ext_str)); shp = scsi_register(shtp,sizeof(gdth_ext_str));
if(shp == NULL) if (shp == NULL)
continue; continue;
ha = HADATA(shp); ha = HADATA(shp);
if (!gdth_init_eisa(eisa_slot,ha)) { if (!gdth_init_eisa(eisa_slot,ha)) {
...@@ -4180,11 +4388,19 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4180,11 +4388,19 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
NUMDATA(shp)->hanum)); NUMDATA(shp)->hanum));
ha->pccb = CMDDATA(shp); ha->pccb = CMDDATA(shp);
#if LINUX_VERSION_CODE >= 0x020322 ha->ccb_phys = 0L;
ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, #if LINUX_VERSION_CODE >= 0x020400
GDTH_SCRATCH_ORD); ha->pdev = NULL;
ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
&ha->scratch_phys);
ha->ccb_phys =
pci_map_single(ha->pdev,ha->pccb,
sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
#else #else
ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
if (ha->pscratch)
ha->scratch_phys = virt_to_bus(ha->pscratch);
ha->ccb_phys = virt_to_bus(ha->pccb);
#endif #endif
ha->scratch_busy = FALSE; ha->scratch_busy = FALSE;
ha->req_first = NULL; ha->req_first = NULL;
...@@ -4199,12 +4415,16 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4199,12 +4415,16 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
printk("GDT-EISA: Error during device scan\n"); printk("GDT-EISA: Error during device scan\n");
--gdth_ctr_count; --gdth_ctr_count;
--gdth_ctr_vcount; --gdth_ctr_vcount;
if (ha->pscratch != NULL) if (ha->pscratch != NULL) {
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020400
free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD); pci_free_consistent(ha->pdev, GDTH_SCRATCH,
ha->pscratch, ha->scratch_phys);
pci_unmap_single(ha->pdev,ha->ccb_phys,
sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
#else #else
scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
#endif #endif
}
#if LINUX_VERSION_CODE >= 0x010346 #if LINUX_VERSION_CODE >= 0x010346
free_irq(ha->irq,ha); free_irq(ha->irq,ha);
#else #else
...@@ -4252,14 +4472,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4252,14 +4472,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
gdth_pci_str pcistr[MAXHA]; gdth_pci_str pcistr[MAXHA];
cnt = gdth_search_pci(pcistr); cnt = gdth_search_pci(pcistr);
printk("GDT: Found %d PCI Storage RAID Controllers\n",cnt); printk("GDT: Found %d PCI Storage RAID Controllers\n",cnt);
gdth_sort_pci(pcistr,cnt); gdth_sort_pci(pcistr,cnt);
for (ctr = 0; ctr < cnt; ++ctr) { for (ctr = 0; ctr < cnt; ++ctr) {
if (gdth_ctr_count >= MAXHA) if (gdth_ctr_count >= MAXHA)
break; break;
shp = scsi_register(shtp,sizeof(gdth_ext_str)); shp = scsi_register(shtp,sizeof(gdth_ext_str));
if(shp == NULL) if (shp == NULL)
continue; continue;
ha = HADATA(shp); ha = HADATA(shp);
if (!gdth_init_pci(&pcistr[ctr],ha)) { if (!gdth_init_pci(&pcistr[ctr],ha)) {
...@@ -4293,11 +4513,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4293,11 +4513,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
NUMDATA(shp)->busnum= 0; NUMDATA(shp)->busnum= 0;
ha->pccb = CMDDATA(shp); ha->pccb = CMDDATA(shp);
#if LINUX_VERSION_CODE >= 0x020322 ha->ccb_phys = 0L;
ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, #if LINUX_VERSION_CODE >= 0x020400
GDTH_SCRATCH_ORD); ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
&ha->scratch_phys);
#else #else
ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
if (ha->pscratch)
ha->scratch_phys = virt_to_bus(ha->pscratch);
#endif #endif
ha->scratch_busy = FALSE; ha->scratch_busy = FALSE;
ha->req_first = NULL; ha->req_first = NULL;
...@@ -4312,12 +4535,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4312,12 +4535,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
printk("GDT-PCI: Error during device scan\n"); printk("GDT-PCI: Error during device scan\n");
--gdth_ctr_count; --gdth_ctr_count;
--gdth_ctr_vcount; --gdth_ctr_vcount;
if (ha->pscratch != NULL) if (ha->pscratch != NULL) {
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020400
free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD); pci_free_consistent(ha->pdev, GDTH_SCRATCH,
ha->pscratch, ha->scratch_phys);
#else #else
scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
#endif #endif
}
#if LINUX_VERSION_CODE >= 0x010346 #if LINUX_VERSION_CODE >= 0x010346
free_irq(ha->irq,ha); free_irq(ha->irq,ha);
#else #else
...@@ -4365,6 +4590,9 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ...@@ -4365,6 +4590,9 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
gdth_timer.function = gdth_timeout; gdth_timer.function = gdth_timeout;
add_timer(&gdth_timer); add_timer(&gdth_timer);
#endif #endif
#ifdef GDTH_IOCTL_CHRDEV
major = register_chrdev(0,"gdth",&gdth_fops);
#endif
#if LINUX_VERSION_CODE >= 0x020100 #if LINUX_VERSION_CODE >= 0x020100
register_reboot_notifier(&gdth_notifier); register_reboot_notifier(&gdth_notifier);
#endif #endif
...@@ -4399,8 +4627,12 @@ int gdth_release(struct Scsi_Host *shp) ...@@ -4399,8 +4627,12 @@ int gdth_release(struct Scsi_Host *shp)
free_dma(shp->dma_channel); free_dma(shp->dma_channel);
} }
#endif #endif
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020400
free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD); pci_free_consistent(ha->pdev, GDTH_SCRATCH,
ha->pscratch, ha->scratch_phys);
if (ha->ccb_phys)
pci_unmap_single(ha->pdev,ha->ccb_phys,
sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
#else #else
scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
#endif #endif
...@@ -4412,6 +4644,9 @@ int gdth_release(struct Scsi_Host *shp) ...@@ -4412,6 +4644,9 @@ int gdth_release(struct Scsi_Host *shp)
#ifdef GDTH_STATISTICS #ifdef GDTH_STATISTICS
del_timer(&gdth_timer); del_timer(&gdth_timer);
#endif #endif
#ifdef GDTH_IOCTL_CHRDEV
unregister_chrdev(major,"gdth");
#endif
#if LINUX_VERSION_CODE >= 0x020100 #if LINUX_VERSION_CODE >= 0x020100
unregister_reboot_notifier(&gdth_notifier); unregister_reboot_notifier(&gdth_notifier);
#endif #endif
...@@ -4507,15 +4742,24 @@ int gdth_eh_bus_reset(Scsi_Cmnd *scp) ...@@ -4507,15 +4742,24 @@ int gdth_eh_bus_reset(Scsi_Cmnd *scp)
unchar b; unchar b;
TRACE2(("gdth_eh_bus_reset()\n")); TRACE2(("gdth_eh_bus_reset()\n"));
#if LINUX_VERSION_CODE >= 0x02053C
hanum = NUMDATA(scp->device->host)->hanum; hanum = NUMDATA(scp->device->host)->hanum;
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
#else
hanum = NUMDATA(scp->host)->hanum;
b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
#endif
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
/* clear command tab */ /* clear command tab */
GDTH_LOCK_HA(ha, flags); GDTH_LOCK_HA(ha, flags);
for (i = 0; i < GDTH_MAXCMDS; ++i) { for (i = 0; i < GDTH_MAXCMDS; ++i) {
cmnd = ha->cmd_tab[i].cmnd; cmnd = ha->cmd_tab[i].cmnd;
#if LINUX_VERSION_CODE >= 0x02053C
if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b) if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b)
#else
if (!SPECIAL_SCP(cmnd) && cmnd->channel == b)
#endif
ha->cmd_tab[i].cmnd = UNUSED_CMND; ha->cmd_tab[i].cmnd = UNUSED_CMND;
} }
GDTH_UNLOCK_HA(ha, flags); GDTH_UNLOCK_HA(ha, flags);
...@@ -4558,16 +4802,31 @@ int gdth_eh_host_reset(Scsi_Cmnd *scp) ...@@ -4558,16 +4802,31 @@ int gdth_eh_host_reset(Scsi_Cmnd *scp)
} }
#endif #endif
int gdth_bios_param(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int *ip) #if LINUX_VERSION_CODE >= 0x020503
int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip)
#elif LINUX_VERSION_CODE >= 0x010300
int gdth_bios_param(Disk *disk,kdev_t dev,int *ip)
#else
int gdth_bios_param(Disk *disk,int dev,int *ip)
#endif
{ {
unchar b, t; unchar b, t;
int hanum; int hanum;
gdth_ha_str *ha; gdth_ha_str *ha;
struct scsi_device *sd;
unsigned capacity;
hanum = NUMDATA(sdev->host)->hanum; #if LINUX_VERSION_CODE >= 0x020503
b = virt_ctr ? NUMDATA(sdev->host)->busnum : sdev->channel; sd = sdev;
t = sdev->id; capacity = cap;
#else
sd = disk->device;
capacity = disk->capacity;
#endif
hanum = NUMDATA(sd->host)->hanum;
b = virt_ctr ? NUMDATA(sd->host)->busnum : sd->channel;
t = sd->id;
TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", hanum, b, t)); TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", hanum, b, t));
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
...@@ -4592,14 +4851,19 @@ int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) ...@@ -4592,14 +4851,19 @@ int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
int hanum; int hanum;
int priority; int priority;
TRACE(("gdth_queuecommand() cmd 0x%x id %d lun %d\n", TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0]));
scp->cmnd[0],scp->device->id,scp->lun));
scp->scsi_done = (void *)done; scp->scsi_done = (void *)done;
scp->SCp.have_data_in = 1; scp->SCp.have_data_in = 1;
scp->SCp.phase = -1; scp->SCp.phase = -1;
scp->SCp.sent_command = -1; scp->SCp.sent_command = -1;
scp->SCp.Status = GDTH_MAP_NONE;
scp->SCp.buffer = (struct scatterlist *)NULL;
#if LINUX_VERSION_CODE >= 0x02053C
hanum = NUMDATA(scp->device->host)->hanum; hanum = NUMDATA(scp->device->host)->hanum;
#else
hanum = NUMDATA(scp->host)->hanum;
#endif
#ifdef GDTH_STATISTICS #ifdef GDTH_STATISTICS
++act_ios; ++act_ios;
#endif #endif
...@@ -4615,6 +4879,667 @@ int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) ...@@ -4615,6 +4879,667 @@ int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
return 0; return 0;
} }
#ifdef GDTH_IOCTL_CHRDEV
static int gdth_open(struct inode *inode, struct file *filep)
{
TRACE(("gdth_open()\n"));
return 0;
}
static int gdth_close(struct inode *inode, struct file *filep)
{
TRACE(("gdth_close()\n"));
return 0;
}
static int gdth_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg)
{
gdth_ha_str *ha;
#if LINUX_VERSION_CODE >= 0x020503
Scsi_Request *srp;
Scsi_Cmnd *scp;
Scsi_Device *sdev;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd *scp;
Scsi_Device *sdev;
#else
Scsi_Cmnd scp;
Scsi_Device sdev;
#endif
ulong flags;
char cmnd[MAX_COMMAND_SIZE];
memset(cmnd, 0xff, 12);
TRACE(("gdth_ioctl() cmd 0x%x\n", cmd));
switch (cmd) {
case GDTIOCTL_CTRCNT:
{
int cnt = gdth_ctr_count;
put_user(cnt, (int *)arg);
break;
}
case GDTIOCTL_DRVERS:
{
int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION;
put_user(ver, (int *)arg);
break;
}
case GDTIOCTL_OSVERS:
{
gdth_ioctl_osvers osv;
osv.version = (unchar)(LINUX_VERSION_CODE >> 16);
osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8);
osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff);
copy_to_user((char *)arg, &osv, sizeof(gdth_ioctl_osvers));
break;
}
case GDTIOCTL_CTRTYPE:
{
gdth_ioctl_ctrtype ctrt;
if (copy_from_user(&ctrt, (char *)arg, sizeof(gdth_ioctl_ctrtype)) ||
ctrt.ionode >= gdth_ctr_count)
return -EFAULT;
ha = HADATA(gdth_ctr_tab[ctrt.ionode]);
if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
ctrt.type = (unchar)((ha->stype>>20) - 0x10);
} else {
if (ha->type != GDT_PCIMPR) {
ctrt.type = (unchar)((ha->stype<<4) + 6);
} else {
ctrt.type =
(ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
if (ha->stype >= 0x300)
ctrt.ext_type = 0x6000 | ha->subdevice_id;
else
ctrt.ext_type = 0x6000 | ha->stype;
}
ctrt.device_id = ha->stype;
ctrt.sub_device_id = ha->subdevice_id;
}
ctrt.info = ha->brd_phys;
ctrt.oem_id = ha->oem_id;
if (copy_to_user((char *)arg, &ctrt, sizeof(gdth_ioctl_ctrtype)))
return -EFAULT;
break;
}
case GDTIOCTL_GENERAL:
{
gdth_ioctl_general gen;
char *buf = NULL;
ulong32 paddr;
int hanum;
if (copy_from_user(&gen, (char *)arg, sizeof(gdth_ioctl_general)) ||
gen.ionode >= gdth_ctr_count)
return -EFAULT;
hanum = gen.ionode;
ha = HADATA(gdth_ctr_tab[hanum]);
if (gen.data_len + gen.sense_len != 0) {
if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len,
FALSE, &paddr)))
return -EFAULT;
if (copy_from_user(buf, (char *)arg + sizeof(gdth_ioctl_general),
gen.data_len + gen.sense_len)) {
gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
return -EFAULT;
}
if (gen.command.OpCode == GDT_IOCTL) {
gen.command.u.ioctl.p_param = paddr;
} else if (gen.command.Service == CACHESERVICE) {
if (ha->cache_feat & SCATTER_GATHER) {
gen.command.u.cache.DestAddr = 0xffffffff;
gen.command.u.cache.sg_canz = 1;
gen.command.u.cache.sg_lst[0].sg_ptr = paddr;
gen.command.u.cache.sg_lst[0].sg_len = gen.data_len;
gen.command.u.cache.sg_lst[1].sg_len = 0;
} else {
gen.command.u.cache.DestAddr = paddr;
gen.command.u.cache.sg_canz = 0;
}
} else if (gen.command.Service == SCSIRAWSERVICE) {
if (ha->raw_feat & SCATTER_GATHER) {
gen.command.u.raw.sdata = 0xffffffff;
gen.command.u.raw.sg_ranz = 1;
gen.command.u.raw.sg_lst[0].sg_ptr = paddr;
gen.command.u.raw.sg_lst[0].sg_len = gen.data_len;
gen.command.u.raw.sg_lst[1].sg_len = 0;
} else {
gen.command.u.raw.sdata = paddr;
gen.command.u.raw.sg_ranz = 0;
}
gen.command.u.raw.sense_data = paddr + gen.data_len;
} else {
gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
return -EFAULT;
}
}
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
srp = scsi_allocate_request(sdev);
if (!srp)
return -ENOMEM;
srp->sr_cmd_len = 12;
srp->sr_use_sg = 0;
gdth_do_req(srp, &gen.command, cmnd, gen.timeout);
gen.status = srp->sr_command->SCp.Status;
gen.info = srp->sr_command->SCp.Message;
scsi_release_request(srp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp)
return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
gdth_do_cmd(scp, &gen.command, cmnd, gen.timeout);
gen.status = scp->SCp.Status;
gen.info = scp->SCp.Message;
scsi_release_command(scp);
scsi_free_host_dev(sdev);
#else
memset(&sdev,0,sizeof(Scsi_Device));
memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = gdth_ctr_tab[hanum];
sdev.id = scp.target = sdev.host->this_id;
scp.device = &sdev;
gdth_do_cmd(&scp, &gen.command, cmnd, gen.timeout);
gen.status = scp.SCp.Status;
gen.info = scp.SCp.Message;
#endif
if (copy_to_user((char *)arg + sizeof(gdth_ioctl_general), buf,
gen.data_len + gen.sense_len)) {
gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
return -EFAULT;
}
if (copy_to_user((char *)arg, &gen,
sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) {
gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
return -EFAULT;
}
gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
break;
}
case GDTIOCTL_EVENT:
{
gdth_ioctl_event evt;
gdth_ha_str *ha;
ulong flags;
if (copy_from_user(&evt, (char *)arg, sizeof(gdth_ioctl_event)) ||
evt.ionode >= gdth_ctr_count)
return -EFAULT;
ha = HADATA(gdth_ctr_tab[evt.ionode]);
if (evt.erase == 0xff) {
if (evt.event.event_source == ES_TEST)
evt.event.event_data.size=sizeof(evt.event.event_data.eu.test);
else if (evt.event.event_source == ES_DRIVER)
evt.event.event_data.size=sizeof(evt.event.event_data.eu.driver);
else if (evt.event.event_source == ES_SYNC)
evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync);
else
evt.event.event_data.size=sizeof(evt.event.event_data.eu.async);
GDTH_LOCK_HA(ha, flags);
gdth_store_event(ha, evt.event.event_source, evt.event.event_idx,
&evt.event.event_data);
GDTH_UNLOCK_HA(ha, flags);
} else if (evt.erase == 0xfe) {
gdth_clear_events();
} else if (evt.erase == 0) {
evt.handle = gdth_read_event(ha, evt.handle, &evt.event);
} else {
gdth_readapp_event(ha, evt.erase, &evt.event);
}
if (copy_to_user((char *)arg, &evt, sizeof(gdth_ioctl_event)))
return -EFAULT;
break;
}
case GDTIOCTL_LOCKDRV:
{
gdth_ioctl_lockdrv ldrv;
unchar i, j;
if (copy_from_user(&ldrv, (char *)arg, sizeof(gdth_ioctl_lockdrv)) ||
ldrv.ionode >= gdth_ctr_count)
return -EFAULT;
ha = HADATA(gdth_ctr_tab[ldrv.ionode]);
for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) {
j = ldrv.drives[i];
if (j >= MAX_HDRIVES || !ha->hdr[j].present)
continue;
if (ldrv.lock) {
GDTH_LOCK_HA(ha, flags);
ha->hdr[j].lock = 1;
GDTH_UNLOCK_HA(ha, flags);
gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j);
gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j);
} else {
GDTH_LOCK_HA(ha, flags);
ha->hdr[j].lock = 0;
GDTH_UNLOCK_HA(ha, flags);
gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j);
gdth_next(ldrv.ionode);
}
}
break;
}
case GDTIOCTL_LOCKCHN:
{
gdth_ioctl_lockchn lchn;
unchar i, j;
if (copy_from_user(&lchn, (char *)arg, sizeof(gdth_ioctl_lockchn)) ||
lchn.ionode >= gdth_ctr_count)
return -EFAULT;
ha = HADATA(gdth_ctr_tab[lchn.ionode]);
i = lchn.channel;
if (i < ha->bus_cnt) {
if (lchn.lock) {
GDTH_LOCK_HA(ha, flags);
ha->raw[i].lock = 1;
GDTH_UNLOCK_HA(ha, flags);
for (j = 0; j < ha->tid_cnt; ++j) {
gdth_wait_completion(lchn.ionode, i, j);
gdth_stop_timeout(lchn.ionode, i, j);
}
} else {
GDTH_LOCK_HA(ha, flags);
ha->raw[i].lock = 0;
GDTH_UNLOCK_HA(ha, flags);
for (j = 0; j < ha->tid_cnt; ++j) {
gdth_start_timeout(lchn.ionode, i, j);
gdth_next(lchn.ionode);
}
}
}
break;
}
case GDTIOCTL_RESCAN:
{
gdth_ioctl_rescan rsc;
gdth_cmd_str cmd;
ushort i, status, hdr_cnt;
ulong32 info;
int hanum, cyls, hds, secs;
if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
rsc.ionode >= gdth_ctr_count)
return -EFAULT;
hanum = rsc.ionode;
ha = HADATA(gdth_ctr_tab[hanum]);
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
srp = scsi_allocate_request(sdev);
if (!srp)
return -ENOMEM;
srp->sr_cmd_len = 12;
srp->sr_use_sg = 0;
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp)
return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
#else
memset(&sdev,0,sizeof(Scsi_Device));
memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = gdth_ctr_tab[hanum];
sdev.id = scp.target = sdev.host->this_id;
scp.device = &sdev;
#endif
if (rsc.flag == 0) {
/* old method: re-init. cache service */
cmd.Service = CACHESERVICE;
cmd.OpCode = GDT_INIT;
cmd.u.cache.DeviceNo = LINUX_OS;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(srp, &cmd, cmnd, 30);
status = (ushort)srp->sr_command->SCp.Status;
info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &cmd, cmnd, 30);
status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message;
#else
gdth_do_cmd(&scp, &cmd, cmnd, 30);
status = (ushort)scp.SCp.Status;
info = (ulong32)scp.SCp.Message;
#endif
i = 0;
hdr_cnt = (status == S_OK ? (ushort)info : 0);
} else {
i = rsc.hdr_no;
hdr_cnt = i + 1;
}
for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) {
cmd.Service = CACHESERVICE;
cmd.OpCode = GDT_INFO;
cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(srp, &cmd, cmnd, 30);
status = (ushort)srp->sr_command->SCp.Status;
info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &cmd, cmnd, 30);
status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message;
#else
gdth_do_cmd(&scp, &cmd, cmnd, 30);
status = (ushort)scp.SCp.Status;
info = (ulong32)scp.SCp.Message;
#endif
GDTH_LOCK_HA(ha, flags);
rsc.hdr_list[i].bus = ha->virt_bus;
rsc.hdr_list[i].target = i;
rsc.hdr_list[i].lun = 0;
if (status != S_OK) {
ha->hdr[i].present = FALSE;
} else {
ha->hdr[i].present = TRUE;
ha->hdr[i].size = info;
/* evaluate mapping */
ha->hdr[i].size &= ~SECS32;
gdth_eval_mapping(ha->hdr[i].size,&cyls,&hds,&secs);
ha->hdr[i].heads = hds;
ha->hdr[i].secs = secs;
/* round size */
ha->hdr[i].size = cyls * hds * secs;
}
GDTH_UNLOCK_HA(ha, flags);
if (status != S_OK)
continue;
/* devtype, cluster info, R/W attribs */
cmd.Service = CACHESERVICE;
cmd.OpCode = GDT_DEVTYPE;
cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(srp, &cmd, cmnd, 30);
status = (ushort)srp->sr_command->SCp.Status;
info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &cmd, cmnd, 30);
status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message;
#else
gdth_do_cmd(&scp, &cmd, cmnd, 30);
status = (ushort)scp.SCp.Status;
info = (ulong32)scp.SCp.Message;
#endif
GDTH_LOCK_HA(ha, flags);
ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0);
GDTH_UNLOCK_HA(ha, flags);
cmd.Service = CACHESERVICE;
cmd.OpCode = GDT_CLUST_INFO;
cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(srp, &cmd, cmnd, 30);
status = (ushort)srp->sr_command->SCp.Status;
info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &cmd, cmnd, 30);
status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message;
#else
gdth_do_cmd(&scp, &cmd, cmnd, 30);
status = (ushort)scp.SCp.Status;
info = (ulong32)scp.SCp.Message;
#endif
GDTH_LOCK_HA(ha, flags);
ha->hdr[i].cluster_type =
((status == S_OK && !shared_access) ? (ushort)info : 0);
GDTH_UNLOCK_HA(ha, flags);
rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
cmd.Service = CACHESERVICE;
cmd.OpCode = GDT_RW_ATTRIBS;
cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(srp, &cmd, cmnd, 30);
status = (ushort)srp->sr_command->SCp.Status;
info = (ulong32)srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &cmd, cmnd, 30);
status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message;
#else
gdth_do_cmd(&scp, &cmd, cmnd, 30);
status = (ushort)scp.SCp.Status;
info = (ulong32)scp.SCp.Message;
#endif
GDTH_LOCK_HA(ha, flags);
ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0);
GDTH_UNLOCK_HA(ha, flags);
}
#if LINUX_VERSION_CODE >= 0x020503
scsi_release_request(srp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command(scp);
scsi_free_host_dev(sdev);
#endif
if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
return -EFAULT;
break;
}
case GDTIOCTL_HDRLIST:
{
gdth_ioctl_rescan rsc;
gdth_cmd_str cmd;
gdth_ha_str *ha;
unchar i;
int hanum;
if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
rsc.ionode >= gdth_ctr_count)
return -EFAULT;
hanum = rsc.ionode;
ha = HADATA(gdth_ctr_tab[hanum]);
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
srp = scsi_allocate_request(sdev);
if (!srp)
return -ENOMEM;
srp->sr_cmd_len = 12;
srp->sr_use_sg = 0;
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp)
return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
#else
memset(&sdev,0,sizeof(Scsi_Device));
memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = gdth_ctr_tab[hanum];
sdev.id = scp.target = sdev.host->this_id;
scp.device = &sdev;
#endif
for (i = 0; i < MAX_HDRIVES; ++i) {
if (!ha->hdr[i].present) {
rsc.hdr_list[i].bus = 0xff;
continue;
}
rsc.hdr_list[i].bus = ha->virt_bus;
rsc.hdr_list[i].target = i;
rsc.hdr_list[i].lun = 0;
rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) {
cmd.Service = CACHESERVICE;
cmd.OpCode = GDT_CLUST_INFO;
cmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(srp, &cmd, cmnd, 30);
if (srp->sr_command->SCp.Status == S_OK)
rsc.hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &cmd, cmnd, 30);
if (scp->SCp.Status == S_OK)
rsc.hdr_list[i].cluster_type = scp->SCp.Message;
#else
gdth_do_cmd(&scp, &cmd, cmnd, 30);
if (scp.SCp.Status == S_OK)
rsc.hdr_list[i].cluster_type = scp.SCp.Message;
#endif
}
}
#if LINUX_VERSION_CODE >= 0x020503
scsi_release_request(srp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command(scp);
scsi_free_host_dev(sdev);
#endif
if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
return -EFAULT;
break;
}
case GDTIOCTL_RESET_BUS:
{
gdth_ioctl_reset res;
int hanum, rval;
if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
res.ionode >= gdth_ctr_count)
return -EFAULT;
hanum = res.ionode;
/* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.5.x */
#if LINUX_VERSION_CODE >= 0x02053C
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_get_command(sdev, GFP_KERNEL);
if (!scp)
return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
scp->device->channel = virt_ctr ? 0 : res.number;
rval = gdth_eh_bus_reset(scp);
res.status = (rval == SUCCESS ? S_OK : S_GENERR);
scsi_put_command(scp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
#if LINUX_VERSION_CODE >= 0x020503
scp = scsi_allocate_device(sdev, 1);
#else
scp = scsi_allocate_device(sdev, 1, FALSE);
#endif
if (!scp)
return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
scp->channel = virt_ctr ? 0 : res.number;
rval = gdth_eh_bus_reset(scp);
res.status = (rval == SUCCESS ? S_OK : S_GENERR);
scsi_release_command(scp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x02015F
memset(&sdev,0,sizeof(Scsi_Device));
memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = gdth_ctr_tab[hanum];
sdev.id = scp.target = sdev.host->this_id;
scp.device = &sdev;
scp.channel = virt_ctr ? 0 : res.number;
rval = gdth_eh_bus_reset(&scp);
res.status = (rval == SUCCESS ? S_OK : S_GENERR);
#else
res.status = S_OK;
#endif
if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
return -EFAULT;
break;
}
case GDTIOCTL_RESET_DRV:
{
gdth_ioctl_reset res;
gdth_cmd_str cmd;
int hanum;
if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES)
return -EFAULT;
hanum = res.ionode;
ha = HADATA(gdth_ctr_tab[hanum]);
if (!ha->hdr[res.number].present)
return 0;
cmd.Service = CACHESERVICE;
cmd.OpCode = GDT_CLUST_RESET;
cmd.u.cache.DeviceNo = res.number;
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
srp = scsi_allocate_request(sdev);
if (!srp)
return -ENOMEM;
srp->sr_cmd_len = 12;
srp->sr_use_sg = 0;
gdth_do_req(srp, &cmd, cmnd, 30);
res.status = (ushort)srp->sr_command->SCp.Status;
scsi_release_request(srp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp)
return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
gdth_do_cmd(scp, &cmd, cmnd, 30);
res.status = (ushort)scp->SCp.Status;
scsi_release_command(scp);
scsi_free_host_dev(sdev);
#else
memset(&sdev,0,sizeof(Scsi_Device));
memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = gdth_ctr_tab[hanum];
sdev.id = scp.target = sdev.host->this_id;
scp.device = &sdev;
gdth_do_cmd(&scp, &cmd, cmnd, 30);
res.status = (ushort)scp.SCp.Status;
#endif
if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
return -EFAULT;
break;
}
default:
break;
}
return 0;
}
#endif
#if LINUX_VERSION_CODE >= 0x010300 #if LINUX_VERSION_CODE >= 0x010300
/* flush routine */ /* flush routine */
static void gdth_flush(int hanum) static void gdth_flush(int hanum)
...@@ -4622,7 +5547,10 @@ static void gdth_flush(int hanum) ...@@ -4622,7 +5547,10 @@ static void gdth_flush(int hanum)
int i; int i;
gdth_ha_str *ha; gdth_ha_str *ha;
gdth_cmd_str gdtcmd; gdth_cmd_str gdtcmd;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
Scsi_Request *srp;
Scsi_Device *sdev;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
Scsi_Device *sdev; Scsi_Device *sdev;
#else #else
...@@ -4635,9 +5563,18 @@ static void gdth_flush(int hanum) ...@@ -4635,9 +5563,18 @@ static void gdth_flush(int hanum)
TRACE2(("gdth_flush() hanum %d\n",hanum)); TRACE2(("gdth_flush() hanum %d\n",hanum));
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_get_command(sdev, GFP_KERNEL); srp = scsi_allocate_request(sdev);
if (!srp)
return;
srp->sr_cmd_len = 12;
srp->sr_use_sg = 0;
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp)
return;
scp->cmd_len = 12; scp->cmd_len = 12;
scp->use_sg = 0; scp->use_sg = 0;
#else #else
...@@ -4657,15 +5594,20 @@ static void gdth_flush(int hanum) ...@@ -4657,15 +5594,20 @@ static void gdth_flush(int hanum)
gdtcmd.u.cache.BlockNo = 1; gdtcmd.u.cache.BlockNo = 1;
gdtcmd.u.cache.sg_canz = 0; gdtcmd.u.cache.sg_canz = 0;
TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i));
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(srp, &gdtcmd, cmnd, 30);
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
#else #else
gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
#endif #endif
} }
} }
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
scsi_put_command(scp); scsi_release_request(srp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command(scp);
scsi_free_host_dev(sdev); scsi_free_host_dev(sdev);
#endif #endif
} }
...@@ -4680,7 +5622,10 @@ void gdth_halt(void) ...@@ -4680,7 +5622,10 @@ void gdth_halt(void)
int hanum; int hanum;
#ifndef __alpha__ #ifndef __alpha__
gdth_cmd_str gdtcmd; gdth_cmd_str gdtcmd;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
Scsi_Request *srp;
Scsi_Device *sdev;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
Scsi_Device *sdev; Scsi_Device *sdev;
#else #else
...@@ -4702,6 +5647,7 @@ void gdth_halt(void) ...@@ -4702,6 +5647,7 @@ void gdth_halt(void)
} }
halt_called = TRUE; halt_called = TRUE;
#endif #endif
printk("GDT: Flushing all host drives .. "); printk("GDT: Flushing all host drives .. ");
for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { for (hanum = 0; hanum < gdth_ctr_count; ++hanum) {
gdth_flush(hanum); gdth_flush(hanum);
...@@ -4709,28 +5655,48 @@ void gdth_halt(void) ...@@ -4709,28 +5655,48 @@ void gdth_halt(void)
#ifndef __alpha__ #ifndef __alpha__
/* controller reset */ /* controller reset */
memset(cmnd, 0xff, MAX_COMMAND_SIZE); memset(cmnd, 0xff, MAX_COMMAND_SIZE);
#if LINUX_VERSION_CODE >= 0x020322 gdtcmd.BoardNode = LOCALBOARD;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_RESET;
TRACE2(("gdth_halt(): reset controller %d\n", hanum));
#if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_get_command(sdev, GFP_KERNEL); srp = scsi_allocate_request(sdev);
if (!srp) {
#if LINUX_VERSION_CODE >= 0x020100
unregister_reboot_notifier(&gdth_notifier);
return NOTIFY_OK;
#else
return;
#endif
}
srp->sr_cmd_len = 12;
srp->sr_use_sg = 0;
gdth_do_req(srp, &gdtcmd, cmnd, 10);
scsi_release_request(srp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp) {
#if LINUX_VERSION_CODE >= 0x020100
unregister_reboot_notifier(&gdth_notifier);
return NOTIFY_OK;
#else
return;
#endif
}
scp->cmd_len = 12; scp->cmd_len = 12;
scp->use_sg = 0; scp->use_sg = 0;
gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
scsi_release_command(scp);
scsi_free_host_dev(sdev);
#else #else
memset(&sdev,0,sizeof(Scsi_Device)); memset(&sdev,0,sizeof(Scsi_Device));
memset(&scp, 0,sizeof(Scsi_Cmnd)); memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = gdth_ctr_tab[hanum]; sdev.host = scp.host = gdth_ctr_tab[hanum];
sdev.id = scp.target = sdev.host->this_id; sdev.id = scp.target = sdev.host->this_id;
scp.device = &sdev; scp.device = &sdev;
#endif
gdtcmd.BoardNode = LOCALBOARD;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_RESET;
TRACE2(("gdth_halt(): reset controller %d\n", hanum));
#if LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
scsi_put_command(scp);
scsi_free_host_dev(sdev);
#else
gdth_do_cmd(&scp, &gdtcmd, cmnd, 10); gdth_do_cmd(&scp, &gdtcmd, cmnd, 10);
#endif #endif
#endif #endif
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* <achim.leubner@intel.com> * <achim.leubner@intel.com>
* *
* $Id: gdth.h,v 1.46 2002/02/05 09:39:53 achim Exp $ * $Id: gdth.h,v 1.48 2003/02/27 14:58:22 achim Exp $
*/ */
#include <linux/version.h> #include <linux/version.h>
...@@ -29,16 +29,16 @@ ...@@ -29,16 +29,16 @@
/* defines, macros */ /* defines, macros */
/* driver version */ /* driver version */
#define GDTH_VERSION_STR "2.05" #define GDTH_VERSION_STR "2.07"
#define GDTH_VERSION 2 #define GDTH_VERSION 2
#define GDTH_SUBVERSION 5 #define GDTH_SUBVERSION 7
/* protocol version */ /* protocol version */
#define PROTOCOL_VERSION 1 #define PROTOCOL_VERSION 1
/* OEM IDs */ /* OEM IDs */
#define OEM_ID_ICP 0x941c #define OEM_ID_ICP 0x941c
#define OEM_ID_INTEL 0x8000 #define OEM_ID_INTEL 0x8000
/* controller classes */ /* controller classes */
#define GDT_ISA 0x01 /* ISA controller */ #define GDT_ISA 0x01 /* ISA controller */
...@@ -134,12 +134,17 @@ ...@@ -134,12 +134,17 @@
#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX #ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX
/* new GDT Rx Controller */ /* new GDT Rx Controller */
#define PCI_DEVICE_ID_VORTEX_GDTNEWRX 0x300 #define PCI_DEVICE_ID_VORTEX_GDTNEWRX 0x300
#endif #endif
#ifndef PCI_DEVICE_ID_INTEL_SRC #ifndef PCI_DEVICE_ID_INTEL_SRC
/* Intel Storage RAID Controller */ /* Intel Storage RAID Controller */
#define PCI_DEVICE_ID_INTEL_SRC 0x600 #define PCI_DEVICE_ID_INTEL_SRC 0x600
#endif
#ifndef PCI_DEVICE_ID_INTEL_SRC_XSCALE
/* Intel Storage RAID Controller */
#define PCI_DEVICE_ID_INTEL_SRC_XSCALE 0x601
#endif #endif
/* limits */ /* limits */
...@@ -153,8 +158,6 @@ ...@@ -153,8 +158,6 @@
#define MAXID 127 #define MAXID 127
#define MAXLUN 8 #define MAXLUN 8
#define MAXBUS 6 #define MAXBUS 6
#define MAX_HDRIVES 100 /* max. host drive count */
#define MAX_LDRIVES 255 /* max. log. drive count */
#define MAX_EVENTS 100 /* event buffer count */ #define MAX_EVENTS 100 /* event buffer count */
#define MAX_RES_ARGS 40 /* device reservation, #define MAX_RES_ARGS 40 /* device reservation,
must be a multiple of 4 */ must be a multiple of 4 */
...@@ -254,6 +257,7 @@ ...@@ -254,6 +257,7 @@
#define CACHE_DRV_INFO 0x07 /* cache drive info */ #define CACHE_DRV_INFO 0x07 /* cache drive info */
#define BOARD_FEATURES 0x15 /* controller features */ #define BOARD_FEATURES 0x15 /* controller features */
#define BOARD_INFO 0x28 /* controller info */ #define BOARD_INFO 0x28 /* controller info */
#define CACHE_READ_OEM_STRING_RECORD 0x84 /* read OEM string record */
#define HOST_GET 0x10001L /* get host drive list */ #define HOST_GET 0x10001L /* get host drive list */
#define IO_CHANNEL 0x00020000L /* default IO channel */ #define IO_CHANNEL 0x00020000L /* default IO channel */
#define INVALID_CHANNEL 0x0000ffffL /* invalid channel */ #define INVALID_CHANNEL 0x0000ffffL /* invalid channel */
...@@ -265,7 +269,7 @@ ...@@ -265,7 +269,7 @@
#define S_CACHE_UNKNOWN 12 /* cache serv.: drive unknown */ #define S_CACHE_UNKNOWN 12 /* cache serv.: drive unknown */
#define S_RAW_SCSI 12 /* raw serv.: target error */ #define S_RAW_SCSI 12 /* raw serv.: target error */
#define S_RAW_ILL 0xff /* raw serv.: illegal */ #define S_RAW_ILL 0xff /* raw serv.: illegal */
#define S_CACHE_RESERV -24 /* cache: reserv. conflict */ #define S_CACHE_RESERV -24 /* cache: reserv. conflict */
/* timeout values */ /* timeout values */
#define INIT_RETRIES 100000 /* 100000 * 1ms = 100s */ #define INIT_RETRIES 100000 /* 100000 * 1ms = 100s */
...@@ -292,10 +296,15 @@ ...@@ -292,10 +296,15 @@
#define MAILBOXREG 0x0c90 /* mailbox reg. (16 bytes) */ #define MAILBOXREG 0x0c90 /* mailbox reg. (16 bytes) */
#define EISAREG 0x0cc0 /* EISA configuration */ #define EISAREG 0x0cc0 /* EISA configuration */
/* DMA memory mappings */
#define GDTH_MAP_NONE 0
#define GDTH_MAP_SINGLE 1
#define GDTH_MAP_SG 2
#define GDTH_MAP_IOCTL 3
/* other defines */ /* other defines */
#define LINUX_OS 8 /* used for cache optim. */ #define LINUX_OS 8 /* used for cache optim. */
#define SCATTER_GATHER 1 /* s/g feature */ #define SCATTER_GATHER 1 /* s/g feature */
#define GDTH_MAXSG 32 /* max. s/g elements */
#define SECS32 0x1f /* round capacity */ #define SECS32 0x1f /* round capacity */
#define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */ #define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */
#define LOCALBOARD 0 /* board node always 0 */ #define LOCALBOARD 0 /* board node always 0 */
...@@ -303,10 +312,7 @@ ...@@ -303,10 +312,7 @@
#define SPEZINDEX 1 /* cmd index unknown service */ #define SPEZINDEX 1 /* cmd index unknown service */
#define GDT_WR_THROUGH 0x100 /* WRITE_THROUGH supported */ #define GDT_WR_THROUGH 0x100 /* WRITE_THROUGH supported */
#include "gdth_ioctl.h"
/* typedefs */
typedef u32 ulong32;
#define PACKED __attribute__((packed))
/* screenservice message */ /* screenservice message */
typedef struct { typedef struct {
...@@ -535,6 +541,50 @@ typedef struct { ...@@ -535,6 +541,50 @@ typedef struct {
unchar ld_error; /* error */ unchar ld_error; /* error */
} PACKED gdth_cdrinfo_str; } PACKED gdth_cdrinfo_str;
/* OEM string */
typedef struct {
ulong32 ctl_version;
ulong32 file_major_version;
ulong32 file_minor_version;
ulong32 buffer_size;
ulong32 cpy_count;
ulong32 ext_error;
ulong32 oem_id;
ulong32 board_id;
} PACKED gdth_oem_str_params;
typedef struct {
unchar product_0_1_name[16];
unchar product_4_5_name[16];
unchar product_cluster_name[16];
unchar product_reserved[16];
unchar scsi_cluster_target_vendor_id[16];
unchar cluster_raid_fw_name[16];
unchar oem_brand_name[16];
unchar oem_raid_type[16];
unchar bios_type[13];
unchar bios_title[50];
unchar oem_company_name[37];
ulong32 pci_id_1;
ulong32 pci_id_2;
unchar validation_status[80];
unchar reserved_1[4];
unchar scsi_host_drive_inquiry_vendor_id[16];
unchar library_file_template[16];
unchar reserved_2[16];
unchar tool_name_1[32];
unchar tool_name_2[32];
unchar tool_name_3[32];
unchar oem_contact_1[84];
unchar oem_contact_2[84];
unchar oem_contact_3[84];
} PACKED gdth_oem_str;
typedef struct {
gdth_oem_str_params params;
gdth_oem_str text;
} PACKED gdth_oem_str_ioctl;
/* board features */ /* board features */
typedef struct { typedef struct {
unchar chaining; /* Chaining supported */ unchar chaining; /* Chaining supported */
...@@ -594,118 +644,6 @@ typedef struct { ...@@ -594,118 +644,6 @@ typedef struct {
gdth_hentry_str entry[MAX_HDRIVES]; /* entries */ gdth_hentry_str entry[MAX_HDRIVES]; /* entries */
} PACKED gdth_hget_str; } PACKED gdth_hget_str;
/* scatter/gather element */
typedef struct {
ulong32 sg_ptr; /* address */
ulong32 sg_len; /* length */
} PACKED gdth_sg_str;
/* command structure */
typedef struct {
ulong32 BoardNode; /* board node (always 0) */
ulong32 CommandIndex; /* command number */
ushort OpCode; /* the command (READ,..) */
union {
struct {
ushort DeviceNo; /* number of cache drive */
ulong32 BlockNo; /* block number */
ulong32 BlockCnt; /* block count */
ulong32 DestAddr; /* dest. addr. (if s/g: -1) */
ulong32 sg_canz; /* s/g element count */
gdth_sg_str sg_lst[GDTH_MAXSG]; /* s/g list */
} PACKED cache; /* cache service cmd. str. */
struct {
ushort param_size; /* size of p_param buffer */
ulong32 subfunc; /* IOCTL function */
ulong32 channel; /* device */
ulong32 p_param; /* buffer */
} PACKED ioctl; /* IOCTL command structure */
struct {
ushort reserved;
union {
struct {
ulong32 msg_handle; /* message handle */
ulong32 msg_addr; /* message buffer address */
} PACKED msg;
unchar data[12]; /* buffer for rtc data, ... */
} su;
} PACKED screen; /* screen service cmd. str. */
struct {
ushort reserved;
ulong32 direction; /* data direction */
ulong32 mdisc_time; /* disc. time (0: no timeout)*/
ulong32 mcon_time; /* connect time(0: no to.) */
ulong32 sdata; /* dest. addr. (if s/g: -1) */
ulong32 sdlen; /* data length (bytes) */
ulong32 clen; /* SCSI cmd. length(6,10,12) */
unchar cmd[12]; /* SCSI command */
unchar target; /* target ID */
unchar lun; /* LUN */
unchar bus; /* SCSI bus number */
unchar priority; /* only 0 used */
ulong32 sense_len; /* sense data length */
ulong32 sense_data; /* sense data addr. */
ulong32 link_p; /* linked cmds (not supp.) */
ulong32 sg_ranz; /* s/g element count */
gdth_sg_str sg_lst[GDTH_MAXSG]; /* s/g list */
} PACKED raw; /* raw service cmd. struct. */
} u;
/* additional variables */
unchar Service; /* controller service */
ushort Status; /* command result */
ulong32 Info; /* additional information */
Scsi_Cmnd *RequestBuffer; /* request buffer */
} PACKED gdth_cmd_str;
/* controller event structure */
#define ES_ASYNC 1
#define ES_DRIVER 2
#define ES_TEST 3
#define ES_SYNC 4
typedef struct {
ushort size; /* size of structure */
union {
char stream[16];
struct {
ushort ionode;
ushort service;
ulong32 index;
} PACKED driver;
struct {
ushort ionode;
ushort service;
ushort status;
ulong32 info;
unchar scsi_coord[3];
} PACKED async;
struct {
ushort ionode;
ushort service;
ushort status;
ulong32 info;
ushort hostdrive;
unchar scsi_coord[3];
unchar sense_key;
} PACKED sync;
struct {
ulong32 l1, l2, l3, l4;
} PACKED test;
} eu;
ulong32 severity;
unchar event_string[256];
} PACKED gdth_evt_data;
typedef struct {
ulong32 first_stamp;
ulong32 last_stamp;
ushort same_count;
ushort event_source;
ushort event_idx;
unchar application;
unchar reserved;
gdth_evt_data event_data;
} PACKED gdth_evt_str;
/* DPRAM structures */ /* DPRAM structures */
...@@ -889,7 +827,9 @@ typedef struct { ...@@ -889,7 +827,9 @@ typedef struct {
ulong32 brd_phys; /* slot number/BIOS address */ ulong32 brd_phys; /* slot number/BIOS address */
gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */ gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */
gdth_cmd_str *pccb; /* address command structure */ gdth_cmd_str *pccb; /* address command structure */
ulong32 ccb_phys; /* phys. address */
char *pscratch; /* scratch (DMA) buffer */ char *pscratch; /* scratch (DMA) buffer */
ulong32 scratch_phys; /* phys. address */
unchar scratch_busy; /* in use? */ unchar scratch_busy; /* in use? */
unchar scan_mode; /* current scan mode */ unchar scan_mode; /* current scan mode */
unchar irq; /* IRQ */ unchar irq; /* IRQ */
...@@ -946,6 +886,10 @@ typedef struct { ...@@ -946,6 +886,10 @@ typedef struct {
#if LINUX_VERSION_CODE >= 0x02015F #if LINUX_VERSION_CODE >= 0x02015F
spinlock_t smp_lock; spinlock_t smp_lock;
#endif #endif
#if LINUX_VERSION_CODE >= 0x020400
struct pci_dev *pdev;
#endif
char oem_name[8];
} gdth_ha_str; } gdth_ha_str;
/* structure for scsi_register(), SCSI bus != 0 */ /* structure for scsi_register(), SCSI bus != 0 */
...@@ -1032,34 +976,145 @@ int gdth_reset(Scsi_Cmnd *); ...@@ -1032,34 +976,145 @@ int gdth_reset(Scsi_Cmnd *);
#endif #endif
const char *gdth_info(struct Scsi_Host *); const char *gdth_info(struct Scsi_Host *);
#if LINUX_VERSION_CODE >= 0x020501
int gdth_bios_param(struct scsi_device *,struct block_device *,sector_t,int *); int gdth_bios_param(struct scsi_device *,struct block_device *,sector_t,int *);
int gdth_proc_info(char *,char **,off_t,int,int,int); int gdth_proc_info(char *,char **,off_t,int,int,int);
int gdth_eh_abort(Scsi_Cmnd *scp); int gdth_eh_abort(Scsi_Cmnd *scp);
int gdth_eh_device_reset(Scsi_Cmnd *scp); int gdth_eh_device_reset(Scsi_Cmnd *scp);
int gdth_eh_bus_reset(Scsi_Cmnd *scp); int gdth_eh_bus_reset(Scsi_Cmnd *scp);
int gdth_eh_host_reset(Scsi_Cmnd *scp); int gdth_eh_host_reset(Scsi_Cmnd *scp);
#define GDTH { .proc_name = "gdth", \ #define GDTH { .proc_name = "gdth", \
.proc_info = gdth_proc_info, \ .proc_info = gdth_proc_info, \
.name = "GDT SCSI Disk Array Controller",\ .name = "GDT SCSI Disk Array Controller",\
.detect = gdth_detect, \ .detect = gdth_detect, \
.release = gdth_release, \ .release = gdth_release, \
.info = gdth_info, \ .info = gdth_info, \
.command = NULL, \ .command = NULL, \
.queuecommand = gdth_queuecommand, \ .queuecommand = gdth_queuecommand, \
.eh_abort_handler = gdth_eh_abort, \ .eh_abort_handler = gdth_eh_abort, \
.eh_device_reset_handler = gdth_eh_device_reset, \ .eh_device_reset_handler = gdth_eh_device_reset, \
.eh_bus_reset_handler = gdth_eh_bus_reset, \ .eh_bus_reset_handler = gdth_eh_bus_reset, \
.eh_host_reset_handler = gdth_eh_host_reset, \ .eh_host_reset_handler = gdth_eh_host_reset, \
.abort = gdth_abort, \ .abort = NULL, \
.reset = gdth_reset, \ .reset = NULL, \
.bios_param = gdth_bios_param, \ .bios_param = gdth_bios_param, \
.can_queue = GDTH_MAXCMDS, \ .can_queue = GDTH_MAXCMDS, \
.this_id = -1, \ .this_id = -1, \
.sg_tablesize = GDTH_MAXSG, \ .sg_tablesize = GDTH_MAXSG, \
.cmd_per_lun = GDTH_MAXC_P_L, \ .cmd_per_lun = GDTH_MAXC_P_L, \
.present = 0, \ .present = 0, \
.unchecked_isa_dma = 1, \ .unchecked_isa_dma = 1, \
.use_clustering = ENABLE_CLUSTERING } .use_clustering = ENABLE_CLUSTERING}
#elif LINUX_VERSION_CODE >= 0x020322
int gdth_bios_param(Disk *,kdev_t,int *);
int gdth_proc_info(char *,char **,off_t,int,int,int);
int gdth_eh_abort(Scsi_Cmnd *scp);
int gdth_eh_device_reset(Scsi_Cmnd *scp);
int gdth_eh_bus_reset(Scsi_Cmnd *scp);
int gdth_eh_host_reset(Scsi_Cmnd *scp);
#define GDTH { proc_name: "gdth", \
proc_info: gdth_proc_info, \
name: "GDT SCSI Disk Array Controller",\
detect: gdth_detect, \
release: gdth_release, \
info: gdth_info, \
command: NULL, \
queuecommand: gdth_queuecommand, \
eh_abort_handler: gdth_eh_abort, \
eh_device_reset_handler: gdth_eh_device_reset, \
eh_bus_reset_handler: gdth_eh_bus_reset, \
eh_host_reset_handler: gdth_eh_host_reset, \
abort: gdth_abort, \
reset: gdth_reset, \
bios_param: gdth_bios_param, \
can_queue: GDTH_MAXCMDS, \
this_id: -1, \
sg_tablesize: GDTH_MAXSG, \
cmd_per_lun: GDTH_MAXC_P_L, \
present: 0, \
unchecked_isa_dma: 1, \
use_clustering: ENABLE_CLUSTERING, \
use_new_eh_code: 1 /* use new error code */ }
#elif LINUX_VERSION_CODE >= 0x02015F
int gdth_bios_param(Disk *,kdev_t,int *);
extern struct proc_dir_entry proc_scsi_gdth;
int gdth_proc_info(char *,char **,off_t,int,int,int);
int gdth_eh_abort(Scsi_Cmnd *scp);
int gdth_eh_device_reset(Scsi_Cmnd *scp);
int gdth_eh_bus_reset(Scsi_Cmnd *scp);
int gdth_eh_host_reset(Scsi_Cmnd *scp);
#define GDTH { proc_dir: &proc_scsi_gdth, \
proc_info: gdth_proc_info, \
name: "GDT SCSI Disk Array Controller",\
detect: gdth_detect, \
release: gdth_release, \
info: gdth_info, \
command: NULL, \
queuecommand: gdth_queuecommand, \
eh_abort_handler: gdth_eh_abort, \
eh_device_reset_handler: gdth_eh_device_reset, \
eh_bus_reset_handler: gdth_eh_bus_reset, \
eh_host_reset_handler: gdth_eh_host_reset, \
abort: gdth_abort, \
reset: gdth_reset, \
bios_param: gdth_bios_param, \
can_queue: GDTH_MAXCMDS, \
this_id: -1, \
sg_tablesize: GDTH_MAXSG, \
cmd_per_lun: GDTH_MAXC_P_L, \
present: 0, \
unchecked_isa_dma: 1, \
use_clustering: ENABLE_CLUSTERING, \
use_new_eh_code: 1 /* use new error code */ }
#elif LINUX_VERSION_CODE >= 0x010300
int gdth_bios_param(Disk *,kdev_t,int *);
extern struct proc_dir_entry proc_scsi_gdth;
int gdth_proc_info(char *,char **,off_t,int,int,int);
#define GDTH { NULL, NULL, \
&proc_scsi_gdth, \
gdth_proc_info, \
"GDT SCSI Disk Array Controller", \
gdth_detect, \
gdth_release, \
gdth_info, \
NULL, \
gdth_queuecommand, \
gdth_abort, \
gdth_reset, \
NULL, \
gdth_bios_param, \
GDTH_MAXCMDS, \
-1, \
GDTH_MAXSG, \
GDTH_MAXC_P_L, \
0, \
1, \
ENABLE_CLUSTERING}
#else
int gdth_bios_param(Disk *,int,int *);
#define GDTH { NULL, NULL, \
"GDT SCSI Disk Array Controller", \
gdth_detect, \
gdth_release, \
gdth_info, \
NULL, \
gdth_queuecommand, \
gdth_abort, \
gdth_reset, \
NULL, \
gdth_bios_param, \
GDTH_MAXCMDS, \
-1, \
GDTH_MAXSG, \
GDTH_MAXC_P_L, \
0, \
1, \
ENABLE_CLUSTERING}
#endif
#endif #endif
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define _GDTH_IOCTL_H #define _GDTH_IOCTL_H
/* gdth_ioctl.h /* gdth_ioctl.h
* $Id: gdth_ioctl.h,v 1.10 2001/05/22 06:28:59 achim Exp $ * $Id: gdth_ioctl.h,v 1.11 2003/02/27 14:59:03 achim Exp $
*/ */
/* IOCTLs */ /* IOCTLs */
...@@ -23,8 +23,136 @@ ...@@ -23,8 +23,136 @@
#define GDTIOCTL_MAGIC 0xaffe0004 #define GDTIOCTL_MAGIC 0xaffe0004
#define EVENT_SIZE 294 #define EVENT_SIZE 294
#define MAX_HDRIVES 100 #define GDTH_MAXSG 32 /* max. s/g elements */
#define MAX_LDRIVES 255 /* max. log. drive count */
#ifdef GDTH_IOCTL_PROC
#define MAX_HDRIVES 100 /* max. host drive count */
#else
#define MAX_HDRIVES MAX_LDRIVES /* max. host drive count */
#endif
/* typedefs */
#ifdef __KERNEL__
typedef u32 ulong32;
#endif
#define PACKED __attribute__((packed))
/* scatter/gather element */
typedef struct {
ulong32 sg_ptr; /* address */
ulong32 sg_len; /* length */
} PACKED gdth_sg_str;
/* command structure */
typedef struct {
ulong32 BoardNode; /* board node (always 0) */
ulong32 CommandIndex; /* command number */
ushort OpCode; /* the command (READ,..) */
union {
struct {
ushort DeviceNo; /* number of cache drive */
ulong32 BlockNo; /* block number */
ulong32 BlockCnt; /* block count */
ulong32 DestAddr; /* dest. addr. (if s/g: -1) */
ulong32 sg_canz; /* s/g element count */
gdth_sg_str sg_lst[GDTH_MAXSG]; /* s/g list */
} PACKED cache; /* cache service cmd. str. */
struct {
ushort param_size; /* size of p_param buffer */
ulong32 subfunc; /* IOCTL function */
ulong32 channel; /* device */
ulong32 p_param; /* buffer */
} PACKED ioctl; /* IOCTL command structure */
struct {
ushort reserved;
union {
struct {
ulong32 msg_handle; /* message handle */
ulong32 msg_addr; /* message buffer address */
} PACKED msg;
unchar data[12]; /* buffer for rtc data, ... */
} su;
} PACKED screen; /* screen service cmd. str. */
struct {
ushort reserved;
ulong32 direction; /* data direction */
ulong32 mdisc_time; /* disc. time (0: no timeout)*/
ulong32 mcon_time; /* connect time(0: no to.) */
ulong32 sdata; /* dest. addr. (if s/g: -1) */
ulong32 sdlen; /* data length (bytes) */
ulong32 clen; /* SCSI cmd. length(6,10,12) */
unchar cmd[12]; /* SCSI command */
unchar target; /* target ID */
unchar lun; /* LUN */
unchar bus; /* SCSI bus number */
unchar priority; /* only 0 used */
ulong32 sense_len; /* sense data length */
ulong32 sense_data; /* sense data addr. */
ulong32 link_p; /* linked cmds (not supp.) */
ulong32 sg_ranz; /* s/g element count */
gdth_sg_str sg_lst[GDTH_MAXSG]; /* s/g list */
} PACKED raw; /* raw service cmd. struct. */
} u;
/* additional variables */
unchar Service; /* controller service */
unchar reserved;
ushort Status; /* command result */
ulong32 Info; /* additional information */
void *RequestBuffer; /* request buffer */
} PACKED gdth_cmd_str;
/* controller event structure */
#define ES_ASYNC 1
#define ES_DRIVER 2
#define ES_TEST 3
#define ES_SYNC 4
typedef struct {
ushort size; /* size of structure */
union {
char stream[16];
struct {
ushort ionode;
ushort service;
ulong32 index;
} PACKED driver;
struct {
ushort ionode;
ushort service;
ushort status;
ulong32 info;
unchar scsi_coord[3];
} PACKED async;
struct {
ushort ionode;
ushort service;
ushort status;
ulong32 info;
ushort hostdrive;
unchar scsi_coord[3];
unchar sense_key;
} PACKED sync;
struct {
ulong32 l1, l2, l3, l4;
} PACKED test;
} eu;
ulong32 severity;
unchar event_string[256];
} PACKED gdth_evt_data;
typedef struct {
ulong32 first_stamp;
ulong32 last_stamp;
ushort same_count;
ushort event_source;
ushort event_idx;
unchar application;
unchar reserved;
gdth_evt_data event_data;
} PACKED gdth_evt_str;
#ifdef GDTH_IOCTL_PROC
/* IOCTL structure (write) */ /* IOCTL structure (write) */
typedef struct { typedef struct {
ulong32 magic; /* IOCTL magic */ ulong32 magic; /* IOCTL magic */
...@@ -106,7 +234,82 @@ typedef struct { ...@@ -106,7 +234,82 @@ typedef struct {
} hdr_list[MAX_HDRIVES]; /* index is host drive number */ } hdr_list[MAX_HDRIVES]; /* index is host drive number */
} iu; } iu;
} gdth_iord_str; } gdth_iord_str;
#endif
#ifdef GDTH_IOCTL_CHRDEV
/* GDTIOCTL_GENERAL */
typedef struct {
ushort ionode; /* controller number */
ushort timeout; /* timeout */
ulong32 info; /* error info */
ushort status; /* status */
ulong data_len; /* data buffer size */
ulong sense_len; /* sense buffer size */
gdth_cmd_str command; /* command */
} gdth_ioctl_general;
/* GDTIOCTL_LOCKDRV */
typedef struct {
ushort ionode; /* controller number */
unchar lock; /* lock/unlock */
unchar drive_cnt; /* drive count */
ushort drives[MAX_HDRIVES]; /* drives */
} gdth_ioctl_lockdrv;
/* GDTIOCTL_LOCKCHN */
typedef struct {
ushort ionode; /* controller number */
unchar lock; /* lock/unlock */
unchar channel; /* channel */
} gdth_ioctl_lockchn;
/* GDTIOCTL_OSVERS */
typedef struct {
unchar version; /* OS version */
unchar subversion; /* OS subversion */
ushort revision; /* revision */
} gdth_ioctl_osvers;
/* GDTIOCTL_CTRTYPE */
typedef struct {
ushort ionode; /* controller number */
unchar type; /* controller type */
ushort info; /* slot etc. */
ushort oem_id; /* OEM ID */
ushort bios_ver; /* not used */
ushort access; /* not used */
ushort ext_type; /* extended type */
ushort device_id; /* device ID */
ushort sub_device_id; /* sub device ID */
} gdth_ioctl_ctrtype;
/* GDTIOCTL_EVENT */
typedef struct {
ushort ionode;
int erase; /* erase event? */
int handle; /* event handle */
gdth_evt_str event;
} gdth_ioctl_event;
/* GDTIOCTL_RESCAN/GDTIOCTL_HDRLIST */
typedef struct {
ushort ionode; /* controller number */
unchar flag; /* add/remove */
ushort hdr_no; /* drive no. */
struct {
unchar bus; /* SCSI bus */
unchar target; /* target ID */
unchar lun; /* LUN */
unchar cluster_type; /* cluster properties */
} hdr_list[MAX_HDRIVES]; /* index is host drive number */
} gdth_ioctl_rescan;
/* GDTIOCTL_RESET_BUS/GDTIOCTL_RESET_DRV */
typedef struct {
ushort ionode; /* controller number */
ushort number; /* bus/host drive number */
ushort status; /* status */
} gdth_ioctl_reset;
#endif #endif
#endif
/* gdth_proc.c /* gdth_proc.c
* $Id: gdth_proc.c,v 1.33 2001/08/10 07:54:39 achim Exp $ * $Id: gdth_proc.c,v 1.35 2003/02/27 15:00:44 achim Exp $
*/ */
#include "gdth_ioctl.h"
#if LINUX_VERSION_CODE >= 0x020407 #if LINUX_VERSION_CODE >= 0x020407
#include <linux/completion.h> #include <linux/completion.h>
#endif #endif
...@@ -33,22 +32,33 @@ int gdth_proc_info(char *buffer,char **start,off_t offset,int length, ...@@ -33,22 +32,33 @@ int gdth_proc_info(char *buffer,char **start,off_t offset,int length,
static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum) static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
{ {
int ret_val; int ret_val = -EINVAL;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
Scsi_Request *scp;
Scsi_Device *sdev;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
Scsi_Device *sdev; Scsi_Device *sdev;
#else #else
Scsi_Cmnd scp; Scsi_Cmnd scp;
Scsi_Device sdev; Scsi_Device sdev;
#endif #endif
#ifdef GDTH_IOCTL_PROC
gdth_iowr_str *piowr; gdth_iowr_str *piowr;
TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
piowr = (gdth_iowr_str *)buffer; piowr = (gdth_iowr_str *)buffer;
#endif
TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]); sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_get_command(sdev, GFP_KERNEL); scp = scsi_allocate_request(sdev);
if (!scp)
return -ENOMEM;
scp->sr_cmd_len = 12;
scp->sr_use_sg = 0;
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp) if (!scp)
return -ENOMEM; return -ENOMEM;
scp->cmd_len = 12; scp->cmd_len = 12;
...@@ -56,7 +66,7 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum) ...@@ -56,7 +66,7 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
#else #else
memset(&sdev,0,sizeof(Scsi_Device)); memset(&sdev,0,sizeof(Scsi_Device));
memset(&scp, 0,sizeof(Scsi_Cmnd)); memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = gdth_ctr_vtab[vh]; sdev.host = scp.host = gdth_ctr_tab[hanum];
sdev.id = scp.target = sdev.host->this_id; sdev.id = scp.target = sdev.host->this_id;
scp.device = &sdev; scp.device = &sdev;
#endif #endif
...@@ -66,6 +76,7 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum) ...@@ -66,6 +76,7 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
buffer += 5; buffer += 5;
length -= 5; length -= 5;
ret_val = gdth_set_asc_info( buffer, length, hanum, scp ); ret_val = gdth_set_asc_info( buffer, length, hanum, scp );
#ifdef GDTH_IOCTL_PROC
} else if (piowr->magic == GDTIOCTL_MAGIC) { } else if (piowr->magic == GDTIOCTL_MAGIC) {
ret_val = gdth_set_bin_info( buffer, length, hanum, scp ); ret_val = gdth_set_bin_info( buffer, length, hanum, scp );
} else { } else {
...@@ -75,19 +86,22 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum) ...@@ -75,19 +86,22 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
printk("GDT: Please update your driver.\n"); printk("GDT: Please update your driver.\n");
else else
printk("GDT: Please update your tool.\n"); printk("GDT: Please update your tool.\n");
ret_val = -EINVAL; #endif
} }
} else {
ret_val = -EINVAL;
} }
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
scsi_put_command(scp); scsi_release_request(scp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command(scp);
scsi_free_host_dev(sdev); scsi_free_host_dev(sdev);
#endif #endif
return ret_val; return ret_val;
} }
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp)
#elif LINUX_VERSION_CODE >= 0x020322
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp) static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
#else #else
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
...@@ -98,6 +112,7 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -98,6 +112,7 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdth_ha_str *ha; gdth_ha_str *ha;
gdth_cmd_str gdtcmd; gdth_cmd_str gdtcmd;
gdth_cpar_str *pcpar; gdth_cpar_str *pcpar;
ulong32 paddr;
char cmnd[MAX_COMMAND_SIZE]; char cmnd[MAX_COMMAND_SIZE];
memset(cmnd, 0xff, 12); memset(cmnd, 0xff, 12);
...@@ -133,7 +148,9 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -133,7 +148,9 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.OpCode = GDT_FLUSH; gdtcmd.OpCode = GDT_FLUSH;
gdtcmd.u.cache.DeviceNo = i; gdtcmd.u.cache.DeviceNo = i;
gdtcmd.u.cache.BlockNo = 1; gdtcmd.u.cache.BlockNo = 1;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
#else #else
gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
...@@ -178,23 +195,25 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -178,23 +195,25 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
} }
if (wb_mode) { if (wb_mode) {
if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE)) if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE, &paddr))
return(-EBUSY); return(-EBUSY);
pcpar = (gdth_cpar_str *)ha->pscratch; pcpar = (gdth_cpar_str *)ha->pscratch;
memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL; gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pcpar); gdtcmd.u.ioctl.p_param = paddr;
gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str); gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str);
gdtcmd.u.ioctl.subfunc = CACHE_CONFIG; gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
gdtcmd.u.ioctl.channel = INVALID_CHANNEL; gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
pcpar->write_back = wb_mode==1 ? 0:1; pcpar->write_back = wb_mode==1 ? 0:1;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
#else #else
gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
#endif #endif
gdth_ioctl_free(hanum, ha->pscratch); gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr);
printk("Done.\n"); printk("Done.\n");
return(orig_length); return(orig_length);
} }
...@@ -203,7 +222,10 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -203,7 +222,10 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
return(-EINVAL); return(-EINVAL);
} }
#if LINUX_VERSION_CODE >= 0x020322 #ifdef GDTH_IOCTL_PROC
#if LINUX_VERSION_CODE >= 0x020503
static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Request *scp)
#elif LINUX_VERSION_CODE >= 0x020322
static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp) static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
#else #else
static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
...@@ -216,7 +238,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -216,7 +238,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdth_iord_str *piord; gdth_iord_str *piord;
gdth_cmd_str *pcmd; gdth_cmd_str *pcmd;
gdth_evt_str *pevt; gdth_evt_str *pevt;
ulong32 *ppadd, add_size, *ppadd2, add_size2, info; ulong32 *ppadd, add_size, *ppadd2, add_size2, info, paddr;
ulong flags; ulong flags;
gdth_cmd_str gdtcmd; gdth_cmd_str gdtcmd;
int drv_cyls, drv_hds, drv_secs; int drv_cyls, drv_hds, drv_secs;
...@@ -273,21 +295,25 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -273,21 +295,25 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
return(-EINVAL); return(-EINVAL);
} }
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2, if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2,
TRUE )) TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str) + add_size + add_size2; piord->size = sizeof(gdth_iord_str) + add_size + add_size2;
if (add_size > 0) { if (add_size > 0) {
memcpy(piord->iu.general.data, piowr->iu.general.data, add_size); memcpy(piord->iu.general.data, piowr->iu.general.data, add_size);
*ppadd = virt_to_bus(piord->iu.general.data); *ppadd = paddr + GDTOFFSOF(gdth_iord_str, iu.general.data[0]);
} }
if (add_size2 > 0) { if (add_size2 > 0) {
memcpy(piord->iu.general.data+add_size, piowr->iu.general.data, add_size2); memcpy(piord->iu.general.data+add_size, piowr->iu.general.data, add_size2);
*ppadd2 = virt_to_bus(piord->iu.general.data+add_size); *ppadd2 = paddr + GDTOFFSOF(gdth_iord_str, iu.general.data[0]) + add_size2;
} }
/* do IOCTL */ /* do IOCTL */
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, pcmd, cmnd, piowr->timeout);
piord->status = (scp->sr_command->SCp.Message << 16) |
scp->sr_command->SCp.Status;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, pcmd, cmnd, piowr->timeout); gdth_do_cmd(scp, pcmd, cmnd, piowr->timeout);
piord->status = (scp->SCp.Message<<16)|scp->SCp.Status; piord->status = (scp->SCp.Message<<16)|scp->SCp.Status;
#else #else
...@@ -297,7 +323,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -297,7 +323,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_DRVERS: case GDTIOCTL_DRVERS:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
...@@ -306,7 +332,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -306,7 +332,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_CTRTYPE: case GDTIOCTL_CTRTYPE:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
...@@ -332,7 +358,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -332,7 +358,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_CTRCNT: case GDTIOCTL_CTRCNT:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
...@@ -341,7 +367,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -341,7 +367,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_OSVERS: case GDTIOCTL_OSVERS:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
...@@ -352,7 +378,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -352,7 +378,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_LOCKDRV: case GDTIOCTL_LOCKDRV:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
for (i = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) { for (i = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
...@@ -378,7 +404,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -378,7 +404,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_LOCKCHN: case GDTIOCTL_LOCKCHN:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
i = piowr->iu.lockchn.channel; i = piowr->iu.lockchn.channel;
if (i < ha->bus_cnt) { if (i < ha->bus_cnt) {
...@@ -406,7 +432,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -406,7 +432,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_EVENT: case GDTIOCTL_EVENT:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
if (piowr->iu.event.erase == 0xff) { if (piowr->iu.event.erase == 0xff) {
...@@ -439,16 +465,19 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -439,16 +465,19 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
piord->status = S_OK; piord->status = S_OK;
break; break;
case GDTIOCTL_SCSI: case GDTIOCTL_SCSI:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) #if LINUX_VERSION_CODE >= 0x020503
return(-EINVAL);
#else
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
memcpy(cmnd, piowr->iu.scsi.cmd, 12); memcpy(cmnd, piowr->iu.scsi.cmd, 12);
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020322
scp->device->id = piowr->iu.scsi.target; scp->target = piowr->iu.scsi.target;
scp->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus; scp->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
scp->cmd_len = piowr->iu.scsi.cmd_len; scp->cmd_len = piowr->iu.scsi.cmd_len;
gdth_do_cmd(scp, pcmd, cmnd, piowr->timeout); gdth_do_cmd(scp, pcmd, cmnd, piowr->timeout);
piord->status = (scp->SCp.Message<<16)|scp->SCp.Status; piord->status = (scp->SCp.Message<<16)|scp->SCp.Status;
...@@ -458,16 +487,48 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -458,16 +487,48 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
scp.cmd_len = piowr->iu.scsi.cmd_len; scp.cmd_len = piowr->iu.scsi.cmd_len;
gdth_do_cmd(&scp, pcmd, cmnd, piowr->timeout); gdth_do_cmd(&scp, pcmd, cmnd, piowr->timeout);
piord->status = (scp.SCp.Message<<16)|scp.SCp.Status; piord->status = (scp.SCp.Message<<16)|scp.SCp.Status;
#endif
#endif #endif
break; break;
case GDTIOCTL_RESET_BUS: case GDTIOCTL_RESET_BUS:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x02053C
scp->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus; {
Scsi_Device *sdev;
Scsi_Cmnd *scmnd;
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scmnd= scsi_get_command(sdev, GFP_KERNEL);
if (!scmnd)
return(-ENOMEM);
scmnd->device->host = scp->sr_host;
scmnd->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
piord->status = (ulong32)gdth_eh_bus_reset( scmnd );
if (piord->status == SUCCESS)
piord->status = S_OK;
else
piord->status = S_GENERR;
scsi_put_command(scmnd);
scsi_free_host_dev(sdev);
}
#elif LINUX_VERSION_CODE >= 0x020503
{
Scsi_Cmnd scmnd;
scmnd.host = scp->sr_host;
scmnd.channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
piord->status = (ulong32)gdth_eh_bus_reset( &scmnd );
if (piord->status == SUCCESS)
piord->status = S_OK;
else
piord->status = S_GENERR;
}
#elif LINUX_VERSION_CODE >= 0x020322
scp->channel = virt_ctr ? 0 : piowr->iu.scsi.bus;
piord->status = (ulong32)gdth_eh_bus_reset( scp ); piord->status = (ulong32)gdth_eh_bus_reset( scp );
if (piord->status == SUCCESS) if (piord->status == SUCCESS)
piord->status = S_OK; piord->status = S_OK;
...@@ -486,7 +547,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -486,7 +547,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_HDRLIST: case GDTIOCTL_HDRLIST:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
...@@ -501,7 +562,12 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -501,7 +562,12 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_CLUST_INFO; gdtcmd.OpCode = GDT_CLUST_INFO;
gdtcmd.u.cache.DeviceNo = i; gdtcmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
if (scp->sr_command->SCp.Status == S_OK)
piord->iu.hdr_list[i].cluster_type =
(unchar)scp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
if (scp->SCp.Status == S_OK) if (scp->SCp.Status == S_OK)
piord->iu.hdr_list[i].cluster_type = piord->iu.hdr_list[i].cluster_type =
...@@ -520,7 +586,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -520,7 +586,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_RESCAN: case GDTIOCTL_RESCAN:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
...@@ -532,7 +598,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -532,7 +598,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_INIT; gdtcmd.OpCode = GDT_INIT;
gdtcmd.u.cache.DeviceNo = LINUX_OS; gdtcmd.u.cache.DeviceNo = LINUX_OS;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->sr_command->SCp.Status;
info = (ulong32)scp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->SCp.Status; status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message; info = (ulong32)scp->SCp.Message;
...@@ -557,7 +627,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -557,7 +627,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_INFO; gdtcmd.OpCode = GDT_INFO;
gdtcmd.u.cache.DeviceNo = k; gdtcmd.u.cache.DeviceNo = k;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->sr_command->SCp.Status;
info = (ulong32)scp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->SCp.Status; status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message; info = (ulong32)scp->SCp.Message;
...@@ -591,7 +665,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -591,7 +665,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_DEVTYPE; gdtcmd.OpCode = GDT_DEVTYPE;
gdtcmd.u.cache.DeviceNo = k; gdtcmd.u.cache.DeviceNo = k;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->sr_command->SCp.Status;
info = (ulong32)scp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->SCp.Status; status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message; info = (ulong32)scp->SCp.Message;
...@@ -609,7 +687,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -609,7 +687,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_CLUST_INFO; gdtcmd.OpCode = GDT_CLUST_INFO;
gdtcmd.u.cache.DeviceNo = k; gdtcmd.u.cache.DeviceNo = k;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->sr_command->SCp.Status;
info = (ulong32)scp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->SCp.Status; status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message; info = (ulong32)scp->SCp.Message;
...@@ -628,7 +710,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -628,7 +710,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_RW_ATTRIBS; gdtcmd.OpCode = GDT_RW_ATTRIBS;
gdtcmd.u.cache.DeviceNo = k; gdtcmd.u.cache.DeviceNo = k;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->sr_command->SCp.Status;
info = (ulong32)scp->sr_command->SCp.Message;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
status = (ushort)scp->SCp.Status; status = (ushort)scp->SCp.Status;
info = (ulong32)scp->SCp.Message; info = (ulong32)scp->SCp.Message;
...@@ -646,7 +732,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -646,7 +732,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break; break;
case GDTIOCTL_RESET_DRV: case GDTIOCTL_RESET_DRV:
if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE )) if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE, &paddr ))
return(-EBUSY); return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str); piord->size = sizeof(gdth_iord_str);
...@@ -656,7 +742,10 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -656,7 +742,10 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_CLUST_RESET; gdtcmd.OpCode = GDT_CLUST_RESET;
gdtcmd.u.cache.DeviceNo = i; gdtcmd.u.cache.DeviceNo = i;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
piord->status = (ushort)scp->sr_command->SCp.Status;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
piord->status = (scp->SCp.Message<<16)|scp->SCp.Status; piord->status = (scp->SCp.Message<<16)|scp->SCp.Status;
#else #else
...@@ -671,6 +760,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) ...@@ -671,6 +760,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
} }
return length; return length;
} }
#endif
static int gdth_get_info(char *buffer,char **start,off_t offset, static int gdth_get_info(char *buffer,char **start,off_t offset,
int length,int vh,int hanum,int busnum) int length,int vh,int hanum,int busnum)
...@@ -678,14 +768,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -678,14 +768,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
int size = 0,len = 0; int size = 0,len = 0;
off_t begin = 0,pos = 0; off_t begin = 0,pos = 0;
gdth_ha_str *ha; gdth_ha_str *ha;
gdth_iord_str *piord;
int id, i, j, k, sec, flag; int id, i, j, k, sec, flag;
int no_mdrv = 0, drv_no, is_mirr; int no_mdrv = 0, drv_no, is_mirr;
ulong32 cnt; ulong32 cnt, paddr;
gdth_cmd_str gdtcmd; gdth_cmd_str gdtcmd;
gdth_evt_str estr; gdth_evt_str estr;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
Scsi_Request *scp;
Scsi_Device *sdev;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
Scsi_Device *sdev; Scsi_Device *sdev;
#else #else
...@@ -710,9 +802,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -710,9 +802,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum)); TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum));
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]); sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_get_command(sdev, GFP_KERNEL); scp = scsi_allocate_request(sdev);
if (!scp)
return -ENOMEM;
scp->sr_cmd_len = 12;
scp->sr_use_sg = 0;
#elif LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp) if (!scp)
return -ENOMEM; return -ENOMEM;
scp->cmd_len = 12; scp->cmd_len = 12;
...@@ -720,13 +819,15 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -720,13 +819,15 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
#else #else
memset(&sdev,0,sizeof(Scsi_Device)); memset(&sdev,0,sizeof(Scsi_Device));
memset(&scp, 0,sizeof(Scsi_Cmnd)); memset(&scp, 0,sizeof(Scsi_Cmnd));
sdev.host = scp.host = gdth_ctr_vtab[vh]; sdev.host = scp.host = gdth_ctr_tab[hanum];
sdev.id = scp.target = sdev.host->this_id; sdev.id = scp.target = sdev.host->this_id;
scp.device = &sdev; scp.device = &sdev;
#endif #endif
#ifdef GDTH_IOCTL_PROC
/* ioctl from tool? */ /* ioctl from tool? */
if (!gdth_ioctl_check_bin(hanum, (ushort)length)) { if (!gdth_ioctl_check_bin(hanum, (ushort)length)) {
#endif
/* request is i.e. "cat /proc/scsi/gdth/0" */ /* request is i.e. "cat /proc/scsi/gdth/0" */
/* format: %-15s\t%-10s\t%-15s\t%s */ /* format: %-15s\t%-10s\t%-15s\t%s */
/* driver parameters */ /* driver parameters */
...@@ -798,7 +899,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -798,7 +899,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
len += size; pos = begin + len; len += size; pos = begin + len;
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE); buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < ha->bus_cnt; ++i) { for (i = 0; i < ha->bus_cnt; ++i) {
...@@ -807,7 +908,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -807,7 +908,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4); pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL; gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pds); gdtcmd.u.ioctl.p_param = paddr + GDTH_SCRATCH/4;
gdtcmd.u.ioctl.param_size = 3*GDTH_SCRATCH/4; gdtcmd.u.ioctl.param_size = 3*GDTH_SCRATCH/4;
gdtcmd.u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN; gdtcmd.u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN;
gdtcmd.u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL; gdtcmd.u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL;
...@@ -818,7 +919,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -818,7 +919,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
sizeof(pds->list[0]); sizeof(pds->list[0]);
if (pds->entries > cnt) if (pds->entries > cnt)
pds->entries = cnt; pds->entries = cnt;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
if (scp->sr_command->SCp.Status != S_OK)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
if (scp->SCp.Status != S_OK) if (scp->SCp.Status != S_OK)
#else #else
...@@ -837,12 +941,15 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -837,12 +941,15 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pdi = (gdth_diskinfo_str *)buf; pdi = (gdth_diskinfo_str *)buf;
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL; gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pdi); gdtcmd.u.ioctl.p_param = paddr;
gdtcmd.u.ioctl.param_size = sizeof(gdth_diskinfo_str); gdtcmd.u.ioctl.param_size = sizeof(gdth_diskinfo_str);
gdtcmd.u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN; gdtcmd.u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
gdtcmd.u.ioctl.channel = gdtcmd.u.ioctl.channel =
ha->raw[i].address | ha->raw[i].id_list[j]; ha->raw[i].address | ha->raw[i].id_list[j];
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
if (scp->sr_command->SCp.Status == S_OK)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
if (scp->SCp.Status == S_OK) if (scp->SCp.Status == S_OK)
#else #else
...@@ -892,13 +999,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -892,13 +999,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pdef = (gdth_defcnt_str *)buf; pdef = (gdth_defcnt_str *)buf;
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL; gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pdef); gdtcmd.u.ioctl.p_param = paddr;
gdtcmd.u.ioctl.param_size = sizeof(gdth_defcnt_str); gdtcmd.u.ioctl.param_size = sizeof(gdth_defcnt_str);
gdtcmd.u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN; gdtcmd.u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN;
gdtcmd.u.ioctl.channel = gdtcmd.u.ioctl.channel =
ha->raw[i].address | ha->raw[i].id_list[j]; ha->raw[i].address | ha->raw[i].id_list[j];
pdef->sddc_type = 0x08; pdef->sddc_type = 0x08;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
if (scp->sr_command->SCp.Status == S_OK)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
if (scp->SCp.Status == S_OK) if (scp->SCp.Status == S_OK)
#else #else
...@@ -920,7 +1030,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -920,7 +1030,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
goto stop_output; goto stop_output;
} }
} }
gdth_ioctl_free(hanum, buf); gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr);
if (!flag) { if (!flag) {
size = sprintf(buffer+len, "\n --\n"); size = sprintf(buffer+len, "\n --\n");
...@@ -932,7 +1042,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -932,7 +1042,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
len += size; pos = begin + len; len += size; pos = begin + len;
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE); buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) { for (i = 0; i < MAX_LDRIVES; ++i) {
...@@ -947,11 +1057,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -947,11 +1057,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pcdi = (gdth_cdrinfo_str *)buf; pcdi = (gdth_cdrinfo_str *)buf;
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL; gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pcdi); gdtcmd.u.ioctl.p_param = paddr;
gdtcmd.u.ioctl.param_size = sizeof(gdth_cdrinfo_str); gdtcmd.u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
gdtcmd.u.ioctl.subfunc = CACHE_DRV_INFO; gdtcmd.u.ioctl.subfunc = CACHE_DRV_INFO;
gdtcmd.u.ioctl.channel = drv_no; gdtcmd.u.ioctl.channel = drv_no;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
if (scp->sr_command->SCp.Status != S_OK)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
if (scp->SCp.Status != S_OK) if (scp->SCp.Status != S_OK)
#else #else
...@@ -1034,7 +1147,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1034,7 +1147,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
if (pos > offset + length) if (pos > offset + length)
goto stop_output; goto stop_output;
} }
gdth_ioctl_free(hanum, buf); gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr);
if (!flag) { if (!flag) {
size = sprintf(buffer+len, "\n --\n"); size = sprintf(buffer+len, "\n --\n");
...@@ -1046,7 +1159,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1046,7 +1159,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
len += size; pos = begin + len; len += size; pos = begin + len;
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE); buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) { for (i = 0; i < MAX_LDRIVES; ++i) {
...@@ -1057,11 +1170,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1057,11 +1170,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pai = (gdth_arrayinf_str *)buf; pai = (gdth_arrayinf_str *)buf;
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL; gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pai); gdtcmd.u.ioctl.p_param = paddr;
gdtcmd.u.ioctl.param_size = sizeof(gdth_arrayinf_str); gdtcmd.u.ioctl.param_size = sizeof(gdth_arrayinf_str);
gdtcmd.u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN; gdtcmd.u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
gdtcmd.u.ioctl.channel = i; gdtcmd.u.ioctl.channel = i;
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
if (scp->sr_command->SCp.Status == S_OK)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
if (scp->SCp.Status == S_OK) if (scp->SCp.Status == S_OK)
#else #else
...@@ -1112,7 +1228,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1112,7 +1228,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
goto stop_output; goto stop_output;
} }
} }
gdth_ioctl_free(hanum, buf); gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr);
if (!flag) { if (!flag) {
size = sprintf(buffer+len, "\n --\n"); size = sprintf(buffer+len, "\n --\n");
...@@ -1124,7 +1240,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1124,7 +1240,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
len += size; pos = begin + len; len += size; pos = begin + len;
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE); buf = gdth_ioctl_alloc(hanum, sizeof(gdth_hget_str), FALSE, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) { for (i = 0; i < MAX_LDRIVES; ++i) {
...@@ -1136,13 +1252,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1136,13 +1252,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
phg = (gdth_hget_str *)buf; phg = (gdth_hget_str *)buf;
gdtcmd.Service = CACHESERVICE; gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL; gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(phg); gdtcmd.u.ioctl.p_param = paddr;
gdtcmd.u.ioctl.param_size = sizeof(gdth_hget_str); gdtcmd.u.ioctl.param_size = sizeof(gdth_hget_str);
gdtcmd.u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN; gdtcmd.u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;
gdtcmd.u.ioctl.channel = i; gdtcmd.u.ioctl.channel = i;
phg->entries = MAX_HDRIVES; phg->entries = MAX_HDRIVES;
phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]);
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
gdth_do_req(scp, &gdtcmd, cmnd, 30);
if (scp->sr_command->SCp.Status != S_OK)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd(scp, &gdtcmd, cmnd, 30); gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
if (scp->SCp.Status != S_OK) if (scp->SCp.Status != S_OK)
#else #else
...@@ -1164,7 +1283,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1164,7 +1283,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
} }
} }
} }
gdth_ioctl_free(hanum, buf); gdth_ioctl_free(hanum, sizeof(gdth_hget_str), buf, paddr);
for (i = 0; i < MAX_HDRIVES; ++i) { for (i = 0; i < MAX_HDRIVES; ++i) {
if (!(ha->hdr[i].present)) if (!(ha->hdr[i].present))
...@@ -1221,20 +1340,27 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1221,20 +1340,27 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
if (id == -1) if (id == -1)
break; break;
} }
#ifdef GDTH_IOCTL_PROC
} else { } else {
gdth_iord_str *piord;
/* request from tool (GDTMON,..) */ /* request from tool (GDTMON,..) */
piord = (gdth_iord_str *)ha->pscratch; piord = (gdth_iord_str *)ha->pscratch;
if (piord == NULL) if (piord == NULL)
goto stop_output; goto stop_output;
length = piord->size; length = piord->size;
memcpy(buffer+len, (char *)piord, length); memcpy(buffer+len, (char *)piord, length);
gdth_ioctl_free(hanum, ha->pscratch); gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr);
len = length; len = length;
} }
#endif
stop_output: stop_output:
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
scsi_put_command(scp); scsi_release_request(scp);
scsi_free_host_dev(sdev);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command(scp);
scsi_free_host_dev(sdev); scsi_free_host_dev(sdev);
#endif #endif
*start = buffer +(offset-begin); *start = buffer +(offset-begin);
...@@ -1246,6 +1372,26 @@ static int gdth_get_info(char *buffer,char **start,off_t offset, ...@@ -1246,6 +1372,26 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
return(len); return(len);
} }
#if LINUX_VERSION_CODE >= 0x020503
static void gdth_do_req(Scsi_Request *scp, gdth_cmd_str *gdtcmd,
char *cmnd, int timeout)
{
unsigned bufflen;
DECLARE_COMPLETION(wait);
TRACE2(("gdth_do_req()\n"));
if (gdtcmd != NULL) {
bufflen = sizeof(gdth_cmd_str);
} else {
bufflen = 0;
}
scp->sr_request->rq_status = RQ_SCSI_BUSY;
scp->sr_request->waiting = &wait;
scsi_do_req(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
wait_for_completion(&wait);
}
#else
static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd, static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
char *cmnd, int timeout) char *cmnd, int timeout)
{ {
...@@ -1266,8 +1412,8 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd, ...@@ -1266,8 +1412,8 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
scp->SCp.this_residual = DEFAULT_PRI; scp->SCp.this_residual = DEFAULT_PRI;
bufflen = 0; bufflen = 0;
} }
scp->request.rq_status = RQ_SCSI_BUSY;
#if LINUX_VERSION_CODE >= 0x020407 #if LINUX_VERSION_CODE >= 0x020407
scp->request.rq_status = RQ_SCSI_BUSY;
scp->request.waiting = &wait; scp->request.waiting = &wait;
scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
wait_for_completion(&wait); wait_for_completion(&wait);
...@@ -1283,46 +1429,53 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd, ...@@ -1283,46 +1429,53 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
down(&sem); down(&sem);
#endif #endif
} }
#endif
void gdth_scsi_done(Scsi_Cmnd *scp) void gdth_scsi_done(Scsi_Cmnd *scp)
{ {
TRACE2(("gdth_scsi_done()\n")); TRACE2(("gdth_scsi_done()\n"));
#if LINUX_VERSION_CODE >= 0x020503
scp->request->rq_status = RQ_SCSI_DONE;
if (scp->request->waiting != NULL)
complete(scp->request->waiting);
#elif LINUX_VERSION_CODE >= 0x020407
scp->request.rq_status = RQ_SCSI_DONE; scp->request.rq_status = RQ_SCSI_DONE;
#if LINUX_VERSION_CODE >= 0x020407
if (scp->request.waiting != NULL) if (scp->request.waiting != NULL)
complete(scp->request.waiting); complete(scp->request.waiting);
#else #else
scp->request.rq_status = RQ_SCSI_DONE;
if (scp->request.sem != NULL) if (scp->request.sem != NULL)
up(scp->request.sem); up(scp->request.sem);
#endif #endif
} }
static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch) static char *gdth_ioctl_alloc(int hanum, int size, int scratch,
ulong32 *paddr)
{ {
gdth_ha_str *ha; gdth_ha_str *ha;
ulong flags; ulong flags;
char *ret_val; char *ret_val;
if (size == 0 || size > GDTH_SCRATCH) if (size == 0)
return FALSE; return NULL;
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
GDTH_LOCK_HA(ha, flags); GDTH_LOCK_HA(ha, flags);
if (scratch) { if (!ha->scratch_busy && size <= GDTH_SCRATCH) {
if (!ha->scratch_busy) { ha->scratch_busy = TRUE;
ha->scratch_busy = TRUE; ret_val = ha->pscratch;
ret_val = ha->pscratch; *paddr = ha->scratch_phys;
} else } else if (scratch) {
ret_val = NULL; ret_val = NULL;
} else { } else {
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020400
ret_val = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, ret_val = pci_alloc_consistent(ha->pdev, size, paddr);
GDTH_SCRATCH_ORD);
#else #else
ret_val = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); ret_val = scsi_init_malloc(size, GFP_ATOMIC | GFP_DMA);
if (ret_val)
*paddr = virt_to_bus(ret_val);
#endif #endif
} }
...@@ -1330,7 +1483,7 @@ static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch) ...@@ -1330,7 +1483,7 @@ static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch)
return ret_val; return ret_val;
} }
static void gdth_ioctl_free(int hanum, char *buf) static void gdth_ioctl_free(int hanum, int size, char *buf, ulong32 paddr)
{ {
gdth_ha_str *ha; gdth_ha_str *ha;
ulong flags; ulong flags;
...@@ -1341,16 +1494,17 @@ static void gdth_ioctl_free(int hanum, char *buf) ...@@ -1341,16 +1494,17 @@ static void gdth_ioctl_free(int hanum, char *buf)
if (buf == ha->pscratch) { if (buf == ha->pscratch) {
ha->scratch_busy = FALSE; ha->scratch_busy = FALSE;
} else { } else {
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020400
free_pages((unsigned long)buf, GDTH_SCRATCH_ORD); pci_free_consistent(ha->pdev, size, buf, paddr);
#else #else
scsi_init_free((void *)buf, GDTH_SCRATCH); scsi_init_free((void *)buf, size);
#endif #endif
} }
GDTH_UNLOCK_HA(ha, flags); GDTH_UNLOCK_HA(ha, flags);
} }
#ifdef GDTH_IOCTL_PROC
static int gdth_ioctl_check_bin(int hanum, ushort size) static int gdth_ioctl_check_bin(int hanum, ushort size)
{ {
gdth_ha_str *ha; gdth_ha_str *ha;
...@@ -1368,7 +1522,7 @@ static int gdth_ioctl_check_bin(int hanum, ushort size) ...@@ -1368,7 +1522,7 @@ static int gdth_ioctl_check_bin(int hanum, ushort size)
GDTH_UNLOCK_HA(ha, flags); GDTH_UNLOCK_HA(ha, flags);
return ret_val; return ret_val;
} }
#endif
static void gdth_wait_completion(int hanum, int busnum, int id) static void gdth_wait_completion(int hanum, int busnum, int id)
{ {
...@@ -1376,23 +1530,39 @@ static void gdth_wait_completion(int hanum, int busnum, int id) ...@@ -1376,23 +1530,39 @@ static void gdth_wait_completion(int hanum, int busnum, int id)
ulong flags; ulong flags;
int i; int i;
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
unchar b; unchar b, t;
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
GDTH_LOCK_HA(ha, flags); GDTH_LOCK_HA(ha, flags);
for (i = 0; i < GDTH_MAXCMDS; ++i) { for (i = 0; i < GDTH_MAXCMDS; ++i) {
scp = ha->cmd_tab[i].cmnd; scp = ha->cmd_tab[i].cmnd;
#if LINUX_VERSION_CODE >= 0x02053C
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
if (!SPECIAL_SCP(scp) && scp->device->id == (unchar)id && t = scp->device->id;
#else
b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
t = scp->target;
#endif
if (!SPECIAL_SCP(scp) && t == (unchar)id &&
b == (unchar)busnum) { b == (unchar)busnum) {
scp->SCp.have_data_in = 0; scp->SCp.have_data_in = 0;
GDTH_UNLOCK_HA(ha, flags); GDTH_UNLOCK_HA(ha, flags);
while (!scp->SCp.have_data_in) while (!scp->SCp.have_data_in)
barrier(); barrier();
#if LINUX_VERSION_CODE >= 0x02053C
GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
scp->scsi_done(scp);
GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
#elif LINUX_VERSION_CODE >= 0x020503
GDTH_LOCK_SCSI_DONE(scp->host, flags);
scp->scsi_done(scp);
GDTH_UNLOCK_SCSI_DONE(scp->host, flags);
#else
GDTH_LOCK_SCSI_DONE(flags); GDTH_LOCK_SCSI_DONE(flags);
scp->scsi_done(scp); scp->scsi_done(scp);
GDTH_UNLOCK_SCSI_DONE(flags); GDTH_UNLOCK_SCSI_DONE(flags);
#endif
GDTH_LOCK_HA(ha, flags); GDTH_LOCK_HA(ha, flags);
} }
} }
...@@ -1404,14 +1574,20 @@ static void gdth_stop_timeout(int hanum, int busnum, int id) ...@@ -1404,14 +1574,20 @@ static void gdth_stop_timeout(int hanum, int busnum, int id)
gdth_ha_str *ha; gdth_ha_str *ha;
ulong flags; ulong flags;
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
unchar b; unchar b, t;
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
GDTH_LOCK_HA(ha, flags); GDTH_LOCK_HA(ha, flags);
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
#if LINUX_VERSION_CODE >= 0x02053C
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
if (scp->device->id == (unchar)id && b == (unchar)busnum) { t = scp->device->id;
#else
b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
t = scp->target;
#endif
if (t == (unchar)id && b == (unchar)busnum) {
TRACE2(("gdth_stop_timeout(): update_timeout()\n")); TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
} }
...@@ -1424,14 +1600,20 @@ static void gdth_start_timeout(int hanum, int busnum, int id) ...@@ -1424,14 +1600,20 @@ static void gdth_start_timeout(int hanum, int busnum, int id)
gdth_ha_str *ha; gdth_ha_str *ha;
ulong flags; ulong flags;
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
unchar b; unchar b, t;
ha = HADATA(gdth_ctr_tab[hanum]); ha = HADATA(gdth_ctr_tab[hanum]);
GDTH_LOCK_HA(ha, flags); GDTH_LOCK_HA(ha, flags);
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
#if LINUX_VERSION_CODE >= 0x02053C
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
if (scp->device->id == (unchar)id && b == (unchar)busnum) { t = scp->device->id;
#else
b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
t = scp->target;
#endif
if (t == (unchar)id && b == (unchar)busnum) {
TRACE2(("gdth_start_timeout(): update_timeout()\n")); TRACE2(("gdth_start_timeout(): update_timeout()\n"));
gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
} }
...@@ -1464,7 +1646,7 @@ static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout) ...@@ -1464,7 +1646,7 @@ static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout)
timer_table[SCSI_TIMER].expires = jiffies + timeout; timer_table[SCSI_TIMER].expires = jiffies + timeout;
timer_active |= 1 << SCSI_TIMER; timer_active |= 1 << SCSI_TIMER;
} else { } else {
if (time_before(jiffies + timeout, timer_table[SCSI_TIMER].expires)) if (jiffies + timeout < timer_table[SCSI_TIMER].expires)
timer_table[SCSI_TIMER].expires = jiffies + timeout; timer_table[SCSI_TIMER].expires = jiffies + timeout;
} }
} }
......
...@@ -2,26 +2,42 @@ ...@@ -2,26 +2,42 @@
#define _GDTH_PROC_H #define _GDTH_PROC_H
/* gdth_proc.h /* gdth_proc.h
* $Id: gdth_proc.h,v 1.11 2001/07/25 15:37:40 achim Exp $ * $Id: gdth_proc.h,v 1.13 2003/02/27 14:59:25 achim Exp $
*/ */
static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum); static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum);
static int gdth_get_info(char *buffer,char **start,off_t offset, static int gdth_get_info(char *buffer,char **start,off_t offset,
int length,int vh,int hanum,int busnum); int length,int vh,int hanum,int busnum);
#if LINUX_VERSION_CODE >= 0x020322 #if LINUX_VERSION_CODE >= 0x020503
static void gdth_do_req(Scsi_Request *srp, gdth_cmd_str *cmd,
char *cmnd, int timeout);
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp);
#ifdef GDTH_IOCTL_PROC
static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Request *scp);
#endif
#elif LINUX_VERSION_CODE >= 0x020322
static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd,
char *cmnd, int timeout);
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp); static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp);
#ifdef GDTH_IOCTL_PROC
static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp); static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp);
#endif
#else #else
static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd,
char *cmnd, int timeout);
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp); static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
#ifdef GDTH_IOCTL_PROC
static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp); static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
#endif #endif
static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, #endif
char *cmnd, int timeout);
static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch); static char *gdth_ioctl_alloc(int hanum, int size, int scratch,
static void gdth_ioctl_free(int hanum, char *buf); ulong32 *paddr);
static void gdth_ioctl_free(int hanum, int size, char *buf, ulong32 paddr);
#ifdef GDTH_IOCTL_PROC
static int gdth_ioctl_check_bin(int hanum, ushort size); static int gdth_ioctl_check_bin(int hanum, ushort size);
#endif
static void gdth_wait_completion(int hanum, int busnum, int id); static void gdth_wait_completion(int hanum, int busnum, int id);
static void gdth_stop_timeout(int hanum, int busnum, int id); static void gdth_stop_timeout(int hanum, int busnum, int id);
static void gdth_start_timeout(int hanum, int busnum, int id); static void gdth_start_timeout(int hanum, int busnum, int id);
......
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