Commit 38ff8f13 authored by Christoph Hellwig's avatar Christoph Hellwig

[PATCH] update qlogic pcmcia support

dito
parent c11f8f40
......@@ -55,7 +55,11 @@
#include <pcmcia/ds.h>
#include <pcmcia/ciscode.h>
extern Scsi_Host_Template qlogicfas_driver_template;
extern void qlogicfas_preset(int port, int irq);
extern struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *);
extern int qlogicfas_bus_reset(Scsi_Cmnd *);
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
......@@ -81,6 +85,7 @@ MODULE_PARM(irq_list, "1-4i");
typedef struct scsi_info_t {
dev_link_t link;
struct Scsi_Host *host;
unsigned short manf_id;
int ndev;
dev_node_t node[8];
......@@ -92,9 +97,6 @@ static int qlogic_event(event_t event, int priority, event_callback_args_t * arg
static dev_link_t *qlogic_attach(void);
static void qlogic_detach(dev_link_t *);
/* Import our driver template */
extern Scsi_Host_Template qlogicfas_driver_template;
#define driver_template qlogicfas_driver_template
static dev_link_t *dev_list = NULL;
......@@ -233,7 +235,6 @@ static void qlogic_config(dev_link_t * link)
info->manf_id = le16_to_cpu(tuple.TupleData[0]);
/* Configure card */
driver_template.module = &__this_module;
link->state |= DEV_CONFIG;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
......@@ -272,46 +273,52 @@ static void qlogic_config(dev_link_t * link)
else
qlogicfas_preset(link->io.BasePort1, link->irq.AssignedIRQ);
scsi_register_host(&driver_template);
tail = &link->dev;
info->ndev = 0;
for (host = scsi_host_get_next(NULL); host; host = scsi_host_get_next(host))
if (host->hostt == &driver_template)
list_for_each_entry (dev, &host->my_devices, siblings) {
u_long arg[2], id;
kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) + ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000);
node = &info->node[info->ndev];
node->minor = 0;
switch (dev->type) {
case TYPE_TAPE:
node->major = SCSI_TAPE_MAJOR;
sprintf(node->dev_name, "st#%04lx", id);
break;
case TYPE_DISK:
case TYPE_MOD:
node->major = SCSI_DISK0_MAJOR;
sprintf(node->dev_name, "sd#%04lx", id);
break;
case TYPE_ROM:
case TYPE_WORM:
node->major = SCSI_CDROM_MAJOR;
sprintf(node->dev_name, "sr#%04lx", id);
break;
default:
node->major = SCSI_GENERIC_MAJOR;
sprintf(node->dev_name, "sg#%04lx", id);
break;
}
*tail = node;
tail = &node->next;
info->ndev++;
}
*tail = NULL;
if (info->ndev == 0)
host = __qlogicfas_detect(&qlogicfas_driver_template);
if (!host) {
printk(KERN_INFO "qlogic_cs: no SCSI devices found\n");
goto out;
}
scsi_add_host(host, NULL);
list_for_each_entry(dev, &host->my_devices, siblings) {
u_long arg[2], id;
kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) + ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000);
node = &info->node[info->ndev];
node->minor = 0;
switch (dev->type) {
case TYPE_TAPE:
node->major = SCSI_TAPE_MAJOR;
sprintf(node->dev_name, "st#%04lx", id);
break;
case TYPE_DISK:
case TYPE_MOD:
node->major = SCSI_DISK0_MAJOR;
sprintf(node->dev_name, "sd#%04lx", id);
break;
case TYPE_ROM:
case TYPE_WORM:
node->major = SCSI_CDROM_MAJOR;
sprintf(node->dev_name, "sr#%04lx", id);
break;
default:
node->major = SCSI_GENERIC_MAJOR;
sprintf(node->dev_name, "sg#%04lx", id);
break;
}
*tail = node;
tail = &node->next;
info->ndev++;
}
*tail = NULL;
info->host = host;
out:
link->state &= ~DEV_CONFIG_PENDING;
return;
......@@ -327,29 +334,22 @@ static void qlogic_config(dev_link_t * link)
static void qlogic_release(u_long arg)
{
dev_link_t *link = (dev_link_t *) arg;
scsi_info_t *info = link->priv;
DEBUG(0, "qlogic_release(0x%p)\n", link);
#warning This does not protect you. You need some real fix for your races.
#if 0
if (GET_USE_COUNT(&__this_module) != 0) {
DEBUG(0, "qlogic_cs: release postponed, device still open\n");
link->state |= DEV_STALE_CONFIG;
return;
}
#endif
scsi_unregister_host(&driver_template);
scsi_remove_host(info->host);
link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
scsi_unregister(info->host);
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_LINK)
qlogic_detach(link);
} /* qlogic_release */
/*====================================================================*/
......@@ -390,7 +390,7 @@ static int qlogic_event(event_t event, int priority, event_callback_args_t * arg
outb(0x04, link->io.BasePort1 + 0xd);
}
/* Ugggglllyyyy!!! */
driver_template.eh_bus_reset_handler(NULL);
qlogicfas_bus_reset(NULL);
}
break;
}
......
......@@ -127,11 +127,6 @@
#endif
#include <linux/module.h>
#ifdef PCMCIA
#undef MODULE
#endif
#include <linux/blk.h> /* to get disk capacity */
#include <linux/kernel.h>
#include <linux/string.h>
......@@ -148,7 +143,6 @@
#include "scsi.h"
#include "hosts.h"
#include "qlogicfas.h"
/*----------------------------------------------------------------*/
/* driver state info, local to driver */
......@@ -166,6 +160,8 @@ static int qlcfg8 = (SLOWCABLE << 7) | (QL_ENABLE_PARITY << 4);
static int qlcfg9 = ((XTALFREQ + 4) / 5);
static int qlcfgc = (FASTCLK << 3) | (FASTSCSI << 4);
int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
/*----------------------------------------------------------------*/
/* The qlogic card uses two register maps - These macros select which one */
#define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd ))
......@@ -631,14 +627,12 @@ void qlogicfas_preset(int port, int irq)
* Look for qlogic card and init if found
*/
int __devinit qlogicfas_detect(Scsi_Host_Template * host)
struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *host)
{
int i, j; /* these are only used by IRQ detect */
int qltyp; /* type of chip */
struct Scsi_Host *hreg; /* registered host structure */
host->proc_name = "qlogicfas";
/* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself
* decodes the address - I check 230 first since MIDI cards are
* typically at 0x330
......@@ -659,7 +653,7 @@ int __devinit qlogicfas_detect(Scsi_Host_Template * host)
release_region(qbase, 0x10);
}
if (qbase == 0x430)
return 0;
return NULL;;
} else
printk(KERN_INFO "Ql: Using preset base address of %03x\n", qbase);
......@@ -726,16 +720,21 @@ int __devinit qlogicfas_detect(Scsi_Host_Template * host)
qltyp, qbase, qlirq, QL_TURBO_PDMA);
host->name = qinfo;
return 1;
return hreg;
err_release_mem:
release_region(qbase, 0x10);
if (host->can_queue)
free_irq(qlirq, do_ql_ihandl);
return 0;
return NULL;;
}
int __devinit qlogicfas_detect(Scsi_Host_Template *sht)
{
return (__qlogicfas_detect(sht) != NULL);
}
/*
* Return bios parameters
*/
......@@ -777,7 +776,7 @@ static int qlogicfas_abort(Scsi_Cmnd * cmd)
* the PCMCIA qlogic_stub code. This wants fixing
*/
static int qlogicfas_bus_reset(Scsi_Cmnd * cmd)
int qlogicfas_bus_reset(Scsi_Cmnd * cmd)
{
qabort = 2;
ql_zap();
......@@ -818,9 +817,27 @@ MODULE_LICENSE("GPL");
/*
* The driver template is also needed for PCMCIA
*/
Scsi_Host_Template qlogicfas_driver_template = QLOGICFAS;
Scsi_Host_Template qlogicfas_driver_template = {
.module = THIS_MODULE,
.name = "qlogicfas",
.proc_name = "qlogicfas",
.detect = qlogicfas_detect,
.info = qlogicfas_info,
.command = qlogicfas_command,
.queuecommand = qlogicfas_queuecommand,
.eh_abort_handler = qlogicfas_abort,
.eh_bus_reset_handler = qlogicfas_bus_reset,
.eh_device_reset_handler= qlogicfas_device_reset,
.eh_host_reset_handler = qlogicfas_host_reset,
.bios_param = qlogicfas_biosparam,
.can_queue = 0,
.this_id = -1,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
};
#ifndef PCMCIA
#define driver_template qlogicfas_driver_template
#include "scsi_module.c"
#endif
#ifndef _QLOGICFAS_H
#define _QLOGICFAS_H
static int qlogicfas_detect(Scsi_Host_Template * );
static const char * qlogicfas_info(struct Scsi_Host *);
static int qlogicfas_command(Scsi_Cmnd *);
static int qlogicfas_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
static int qlogicfas_abort(Scsi_Cmnd *);
static int qlogicfas_bus_reset(Scsi_Cmnd *);
static int qlogicfas_device_reset(Scsi_Cmnd *);
static int qlogicfas_host_reset(Scsi_Cmnd *);
static int qlogicfas_biosparam(struct scsi_device *, struct block_device *,
sector_t, int[]);
#define QLOGICFAS { \
.detect = qlogicfas_detect, \
.info = qlogicfas_info, \
.command = qlogicfas_command, \
.queuecommand = qlogicfas_queuecommand, \
.eh_abort_handler = qlogicfas_abort, \
.eh_bus_reset_handler = qlogicfas_bus_reset, \
.eh_device_reset_handler = qlogicfas_device_reset, \
.eh_host_reset_handler = qlogicfas_host_reset, \
.bios_param = qlogicfas_biosparam, \
.can_queue = 0, \
.this_id = -1, \
.sg_tablesize = SG_ALL, \
.cmd_per_lun = 1, \
.use_clustering = DISABLE_CLUSTERING \
}
#endif /* _QLOGICFAS_H */
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