Commit 3f9b23fa authored by Alan Cox's avatar Alan Cox Committed by James Bottomley

[PATCH] update qlogic stub to match qlogic updates

parent b2cfd2fb
...@@ -50,8 +50,6 @@ ...@@ -50,8 +50,6 @@
#include <../drivers/scsi/qlogicfas.h> #include <../drivers/scsi/qlogicfas.h>
#define qlogic_reset(h) qlogicfas_reset(h, 0)
#include <pcmcia/version.h> #include <pcmcia/version.h>
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
#include <pcmcia/cs.h> #include <pcmcia/cs.h>
...@@ -65,8 +63,7 @@ extern void qlogicfas_preset(int port, int irq); ...@@ -65,8 +63,7 @@ extern void qlogicfas_preset(int port, int irq);
static int pc_debug = PCMCIA_DEBUG; static int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i"); MODULE_PARM(pc_debug, "i");
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static char *version = static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)";
"qlogic_cs.c 1.79 2000/06/12 21:27:26 (David Hinds)";
#else #else
#define DEBUG(n, args...) #define DEBUG(n, args...)
#endif #endif
...@@ -76,7 +73,7 @@ static char *version = ...@@ -76,7 +73,7 @@ static char *version =
/* Parameters that can be set with 'insmod' */ /* Parameters that can be set with 'insmod' */
/* Bit map of interrupts to choose from */ /* Bit map of interrupts to choose from */
static u_int irq_mask = 0xdeb8; static unsigned int irq_mask = 0xdeb8;
static int irq_list[4] = { -1 }; static int irq_list[4] = { -1 };
MODULE_PARM(irq_mask, "i"); MODULE_PARM(irq_mask, "i");
...@@ -85,20 +82,21 @@ MODULE_PARM(irq_list, "1-4i"); ...@@ -85,20 +82,21 @@ MODULE_PARM(irq_list, "1-4i");
/*====================================================================*/ /*====================================================================*/
typedef struct scsi_info_t { typedef struct scsi_info_t {
dev_link_t link; dev_link_t link;
u_short manf_id; unsigned short manf_id;
int ndev; int ndev;
dev_node_t node[8]; dev_node_t node[8];
} scsi_info_t; } scsi_info_t;
static void qlogic_release(u_long arg); static void qlogic_release(u_long arg);
static int qlogic_event(event_t event, int priority, static int qlogic_event(event_t event, int priority, event_callback_args_t * args);
event_callback_args_t *args);
static dev_link_t *qlogic_attach(void); static dev_link_t *qlogic_attach(void);
static void qlogic_detach(dev_link_t *); static void qlogic_detach(dev_link_t *);
static Scsi_Host_Template driver_template = QLOGICFAS; /* Import our driver template */
extern Scsi_Host_Template qlogicfas_driver_template;
#define driver_template qlogicfas_driver_template
static dev_link_t *dev_list = NULL; static dev_link_t *dev_list = NULL;
...@@ -108,97 +106,97 @@ static dev_info_t dev_info = "qlogic_cs"; ...@@ -108,97 +106,97 @@ static dev_info_t dev_info = "qlogic_cs";
static void cs_error(client_handle_t handle, int func, int ret) static void cs_error(client_handle_t handle, int func, int ret)
{ {
error_info_t err = { func, ret }; error_info_t err = { func, ret };
CardServices(ReportError, handle, &err); CardServices(ReportError, handle, &err);
} }
/*====================================================================*/ /*====================================================================*/
static dev_link_t *qlogic_attach(void) static dev_link_t *qlogic_attach(void)
{ {
scsi_info_t *info; scsi_info_t *info;
client_reg_t client_reg; client_reg_t client_reg;
dev_link_t *link; dev_link_t *link;
int i, ret; int i, ret;
DEBUG(0, "qlogic_attach()\n"); DEBUG(0, "qlogic_attach()\n");
/* Create new SCSI device */ /* Create new SCSI device */
info = kmalloc(sizeof(*info), GFP_KERNEL); info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) return NULL; if (!info)
memset(info, 0, sizeof(*info)); return NULL;
link = &info->link; link->priv = info; memset(info, 0, sizeof(*info));
link->release.function = &qlogic_release; link = &info->link;
link->release.data = (u_long)link; link->priv = info;
link->release.function = &qlogic_release;
link->io.NumPorts1 = 16; link->release.data = (u_long) link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 10; link->io.NumPorts1 = 16;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; link->io.IOAddrLines = 10;
if (irq_list[0] == -1) link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo2 = irq_mask; link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
else if (irq_list[0] == -1)
for (i = 0; i < 4; i++) link->irq.IRQInfo2 = irq_mask;
link->irq.IRQInfo2 |= 1 << irq_list[i]; else
link->conf.Attributes = CONF_ENABLE_IRQ; for (i = 0; i < 4; i++)
link->conf.Vcc = 50; link->irq.IRQInfo2 |= 1 << irq_list[i];
link->conf.IntType = INT_MEMORY_AND_IO; link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Present = PRESENT_OPTION; link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
/* Register with Card Services */ link->conf.Present = PRESENT_OPTION;
link->next = dev_list;
dev_list = link; /* Register with Card Services */
client_reg.dev_info = &dev_info; link->next = dev_list;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; dev_list = link;
client_reg.event_handler = &qlogic_event; client_reg.dev_info = &dev_info;
client_reg.EventMask = client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | client_reg.event_handler = &qlogic_event;
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; client_reg.Version = 0x0210;
client_reg.Version = 0x0210; client_reg.event_callback_args.client_data = link;
client_reg.event_callback_args.client_data = link; ret = CardServices(RegisterClient, &link->handle, &client_reg);
ret = CardServices(RegisterClient, &link->handle, &client_reg); if (ret != 0) {
if (ret != 0) { cs_error(link->handle, RegisterClient, ret);
cs_error(link->handle, RegisterClient, ret); qlogic_detach(link);
qlogic_detach(link); return NULL;
return NULL; }
}
return link;
return link; } /* qlogic_attach */
} /* qlogic_attach */
/*====================================================================*/ /*====================================================================*/
static void qlogic_detach(dev_link_t *link) static void qlogic_detach(dev_link_t * link)
{ {
dev_link_t **linkp; dev_link_t **linkp;
DEBUG(0, "qlogic_detach(0x%p)\n", link); DEBUG(0, "qlogic_detach(0x%p)\n", link);
/* Locate device structure */ /* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link) break; if (*linkp == link)
if (*linkp == NULL) break;
return; if (*linkp == NULL)
return;
del_timer(&link->release); del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) { if (link->state & DEV_CONFIG) {
qlogic_release((u_long)link); qlogic_release((u_long) link);
if (link->state & DEV_STALE_CONFIG) { if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK; link->state |= DEV_STALE_LINK;
return; return;
}
} }
}
if (link->handle) if (link->handle)
CardServices(DeregisterClient, link->handle); CardServices(DeregisterClient, link->handle);
/* Unlink device structure, free bits */ /* Unlink device structure, free bits */
*linkp = link->next; *linkp = link->next;
kfree(link->priv); kfree(link->priv);
} /* qlogic_detach */ } /* qlogic_detach */
/*====================================================================*/ /*====================================================================*/
...@@ -208,220 +206,216 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed ...@@ -208,220 +206,216 @@ while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
#define CFG_CHECK(fn, args...) \ #define CFG_CHECK(fn, args...) \
if (CardServices(fn, args) != 0) goto next_entry if (CardServices(fn, args) != 0) goto next_entry
static void qlogic_config(dev_link_t *link) static void qlogic_config(dev_link_t * link)
{ {
client_handle_t handle = link->handle; client_handle_t handle = link->handle;
scsi_info_t *info = link->priv; scsi_info_t *info = link->priv;
tuple_t tuple; tuple_t tuple;
cisparse_t parse; cisparse_t parse;
int i, last_ret, last_fn; int i, last_ret, last_fn;
u_short tuple_data[32]; unsigned short tuple_data[32];
Scsi_Device *dev; Scsi_Device *dev;
dev_node_t **tail, *node; dev_node_t **tail, *node;
struct Scsi_Host *host; struct Scsi_Host *host;
DEBUG(0, "qlogic_config(0x%p)\n", link); DEBUG(0, "qlogic_config(0x%p)\n", link);
tuple.TupleData = (cisdata_t *)tuple_data; tuple.TupleData = (cisdata_t *) tuple_data;
tuple.TupleDataMax = 64; tuple.TupleDataMax = 64;
tuple.TupleOffset = 0; tuple.TupleOffset = 0;
tuple.DesiredTuple = CISTPL_CONFIG; tuple.DesiredTuple = CISTPL_CONFIG;
CS_CHECK(GetFirstTuple, handle, &tuple); CS_CHECK(GetFirstTuple, handle, &tuple);
CS_CHECK(GetTupleData, handle, &tuple); CS_CHECK(GetTupleData, handle, &tuple);
CS_CHECK(ParseTuple, handle, &tuple, &parse); CS_CHECK(ParseTuple, handle, &tuple, &parse);
link->conf.ConfigBase = parse.config.base; link->conf.ConfigBase = parse.config.base;
tuple.DesiredTuple = CISTPL_MANFID; tuple.DesiredTuple = CISTPL_MANFID;
if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) && if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) && (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS))
(CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS)) info->manf_id = le16_to_cpu(tuple.TupleData[0]);
info->manf_id = le16_to_cpu(tuple.TupleData[0]);
/* Configure card */
/* Configure card */ driver_template.module = &__this_module;
driver_template.module = &__this_module; link->state |= DEV_CONFIG;
link->state |= DEV_CONFIG;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, handle, &tuple);
CS_CHECK(GetFirstTuple, handle, &tuple); while (1) {
while (1) { CFG_CHECK(GetTupleData, handle, &tuple);
CFG_CHECK(GetTupleData, handle, &tuple); CFG_CHECK(ParseTuple, handle, &tuple, &parse);
CFG_CHECK(ParseTuple, handle, &tuple, &parse); link->conf.ConfigIndex = parse.cftable_entry.index;
link->conf.ConfigIndex = parse.cftable_entry.index; link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
link->io.BasePort1 = parse.cftable_entry.io.win[0].base; link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; if (link->io.BasePort1 != 0) {
if (link->io.BasePort1 != 0) { i = CardServices(RequestIO, handle, &link->io);
i = CardServices(RequestIO, handle, &link->io); if (i == CS_SUCCESS)
if (i == CS_SUCCESS) break; break;
}
next_entry:
CS_CHECK(GetNextTuple, handle, &tuple);
} }
next_entry:
CS_CHECK(GetNextTuple, handle, &tuple); CS_CHECK(RequestIRQ, handle, &link->irq);
} CS_CHECK(RequestConfiguration, handle, &link->conf);
CS_CHECK(RequestIRQ, handle, &link->irq); if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
CS_CHECK(RequestConfiguration, handle, &link->conf); /* set ATAcmd */
outb(0xb4, link->io.BasePort1 + 0xd);
if ((info->manf_id == MANFID_MACNICA) || outb(0x24, link->io.BasePort1 + 0x9);
(info->manf_id == MANFID_PIONEER) || outb(0x04, link->io.BasePort1 + 0xd);
(info->manf_id == 0x0098)) {
/* set ATAcmd */
outb(0xb4, link->io.BasePort1+0xd);
outb(0x24, link->io.BasePort1+0x9);
outb(0x04, link->io.BasePort1+0xd);
}
/* A bad hack... */
release_region(link->io.BasePort1, link->io.NumPorts1);
/* The KXL-810AN has a bigger IO port window */
if (link->io.NumPorts1 == 32)
qlogicfas_preset(link->io.BasePort1+16, link->irq.AssignedIRQ);
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) /* A bad hack... */
printk(KERN_INFO "qlogic_cs: no SCSI devices found\n"); release_region(link->io.BasePort1, link->io.NumPorts1);
link->state &= ~DEV_CONFIG_PENDING; /* The KXL-810AN has a bigger IO port window */
return; if (link->io.NumPorts1 == 32)
qlogicfas_preset(link->io.BasePort1 + 16, link->irq.AssignedIRQ);
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)
printk(KERN_INFO "qlogic_cs: no SCSI devices found\n");
link->state &= ~DEV_CONFIG_PENDING;
return;
cs_failed: cs_failed:
cs_error(link->handle, last_fn, last_ret); cs_error(link->handle, last_fn, last_ret);
qlogic_release((u_long)link); qlogic_release((u_long) link);
return; return;
} /* qlogic_config */ } /* qlogic_config */
/*====================================================================*/ /*====================================================================*/
static void qlogic_release(u_long arg) static void qlogic_release(u_long arg)
{ {
dev_link_t *link = (dev_link_t *)arg; dev_link_t *link = (dev_link_t *) arg;
DEBUG(0, "qlogic_release(0x%p)\n", link); DEBUG(0, "qlogic_release(0x%p)\n", link);
if (GET_USE_COUNT(&__this_module) != 0) { if (GET_USE_COUNT(&__this_module) != 0) {
DEBUG(0, "qlogic_cs: release postponed, device still open\n"); DEBUG(0, "qlogic_cs: release postponed, device still open\n");
link->state |= DEV_STALE_CONFIG; link->state |= DEV_STALE_CONFIG;
return; return;
} }
scsi_unregister_host(&driver_template); scsi_unregister_host(&driver_template);
link->dev = NULL; link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle); CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io); CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq); CardServices(ReleaseIRQ, link->handle, &link->irq);
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_LINK) if (link->state & DEV_STALE_LINK)
qlogic_detach(link); qlogic_detach(link);
} /* qlogic_release */ } /* qlogic_release */
/*====================================================================*/ /*====================================================================*/
static int qlogic_event(event_t event, int priority, static int qlogic_event(event_t event, int priority, event_callback_args_t * args)
event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
DEBUG(1, "qlogic_event(0x%06x)\n", event); DEBUG(1, "qlogic_event(0x%06x)\n", event);
switch (event) { switch (event) {
case CS_EVENT_CARD_REMOVAL: case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT; link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) if (link->state & DEV_CONFIG)
mod_timer(&link->release, jiffies + HZ/20); mod_timer(&link->release, jiffies + HZ / 20);
break; break;
case CS_EVENT_CARD_INSERTION: case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
qlogic_config(link); qlogic_config(link);
break; break;
case CS_EVENT_PM_SUSPEND: case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND; link->state |= DEV_SUSPEND;
/* Fall through... */ /* Fall through... */
case CS_EVENT_RESET_PHYSICAL: case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) if (link->state & DEV_CONFIG)
CardServices(ReleaseConfiguration, link->handle); CardServices(ReleaseConfiguration, link->handle);
break; break;
case CS_EVENT_PM_RESUME: case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND; link->state &= ~DEV_SUSPEND;
/* Fall through... */ /* Fall through... */
case CS_EVENT_CARD_RESET: case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) { if (link->state & DEV_CONFIG) {
scsi_info_t *info = link->priv; scsi_info_t *info = link->priv;
CardServices(RequestConfiguration, link->handle, &link->conf); CardServices(RequestConfiguration, link->handle, &link->conf);
if ((info->manf_id == MANFID_MACNICA) || if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
(info->manf_id == MANFID_PIONEER) || outb(0x80, link->io.BasePort1 + 0xd);
(info->manf_id == 0x0098)) { outb(0x24, link->io.BasePort1 + 0x9);
outb( 0x80, link->io.BasePort1+0xd); outb(0x04, link->io.BasePort1 + 0xd);
outb( 0x24, link->io.BasePort1+0x9); }
outb( 0x04, link->io.BasePort1+0xd); /* Ugggglllyyyy!!! */
} driver_template.eh_bus_reset_handler(NULL);
qlogic_reset(NULL); }
break;
} }
break; return 0;
} } /* qlogic_event */
return 0;
} /* qlogic_event */
/*====================================================================*/ /*====================================================================*/
static int __init init_qlogic_cs(void) { static int __init init_qlogic_cs(void)
servinfo_t serv; {
DEBUG(0, "%s\n", version); servinfo_t serv;
CardServices(GetCardServicesInfo, &serv); DEBUG(0, "%s\n", version);
if (serv.Revision != CS_RELEASE_CODE) { CardServices(GetCardServicesInfo, &serv);
printk(KERN_NOTICE "qlogic_cs: Card Services release " if (serv.Revision != CS_RELEASE_CODE) {
"does not match!\n"); printk(KERN_NOTICE "qlogic_cs: Card Services release " "does not match!\n");
return -1; return -1;
} }
register_pccard_driver(&dev_info, &qlogic_attach, &qlogic_detach); register_pccard_driver(&dev_info, &qlogic_attach, &qlogic_detach);
return 0; return 0;
} }
static void __exit exit_qlogic_cs(void) { static void __exit exit_qlogic_cs(void)
DEBUG(0, "qlogic_cs: unloading\n"); {
unregister_pccard_driver(&dev_info); DEBUG(0, "qlogic_cs: unloading\n");
while (dev_list != NULL) unregister_pccard_driver(&dev_info);
qlogic_detach(dev_list); while (dev_list != NULL)
qlogic_detach(dev_list);
} }
module_init(init_qlogic_cs); module_init(init_qlogic_cs);
......
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