Commit 4f95529a authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] parallel port

parent 8108f00c
...@@ -227,17 +227,3 @@ EXPORT_SYMBOL(parport_daisy_init); ...@@ -227,17 +227,3 @@ EXPORT_SYMBOL(parport_daisy_init);
EXPORT_SYMBOL(parport_find_device); EXPORT_SYMBOL(parport_find_device);
EXPORT_SYMBOL(parport_find_class); EXPORT_SYMBOL(parport_find_class);
#endif #endif
void inc_parport_count(void)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
void dec_parport_count(void)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
...@@ -195,51 +195,40 @@ static void amiga_restore_state(struct parport *p, struct parport_state *s) ...@@ -195,51 +195,40 @@ static void amiga_restore_state(struct parport *p, struct parport_state *s)
mb(); mb();
} }
static void amiga_inc_use_count(void)
{
MOD_INC_USE_COUNT;
}
static void amiga_dec_use_count(void)
{
MOD_DEC_USE_COUNT;
}
static struct parport_operations pp_amiga_ops = { static struct parport_operations pp_amiga_ops = {
amiga_write_data, .write_data = amiga_write_data,
amiga_read_data, .read_data = amiga_read_data,
amiga_write_control, .write_control = amiga_write_control,
amiga_read_control, .read_control = amiga_read_control,
amiga_frob_control, .frob_control = amiga_frob_control,
amiga_read_status, .read_status = amiga_read_status,
amiga_enable_irq, .enable_irq = amiga_enable_irq,
amiga_disable_irq, .disable_irq = amiga_disable_irq,
amiga_data_forward, .data_forward = amiga_data_forward,
amiga_data_reverse, .data_reverse = amiga_data_reverse,
amiga_init_state, .init_state = amiga_init_state,
amiga_save_state, .save_state = amiga_save_state,
amiga_restore_state, .restore_state = amiga_restore_state,
amiga_inc_use_count, .epp_write_data = parport_ieee1284_epp_write_data,
amiga_dec_use_count, .epp_read_data = parport_ieee1284_epp_read_data,
.epp_write_addr = parport_ieee1284_epp_write_addr,
.epp_read_addr = parport_ieee1284_epp_read_addr,
parport_ieee1284_epp_write_data, .ecp_write_data = parport_ieee1284_ecp_write_data,
parport_ieee1284_epp_read_data, .ecp_read_data = parport_ieee1284_ecp_read_data,
parport_ieee1284_epp_write_addr, .ecp_write_addr = parport_ieee1284_ecp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data, .compat_write_data = parport_ieee1284_write_compat,
parport_ieee1284_ecp_read_data, .nibble_read_data = parport_ieee1284_read_nibble,
parport_ieee1284_ecp_write_addr, .byte_read_data = parport_ieee1284_read_byte,
parport_ieee1284_write_compat, .owner = THIS_MODULE,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
}; };
/* ----------- Initialisation code --------------------------------- */ /* ----------- Initialisation code --------------------------------- */
......
...@@ -65,56 +65,41 @@ static unsigned char arc_read_data(struct parport *p) ...@@ -65,56 +65,41 @@ static unsigned char arc_read_data(struct parport *p)
return data_copy; return data_copy;
} }
static void arc_inc_use_count(void)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
static void arc_dec_use_count(void)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations parport_arc_ops = static struct parport_operations parport_arc_ops =
{ {
arc_write_data, .write_data = arc_write_data,
arc_read_data, .read_data = arc_read_data,
arc_write_control, .write_control = arc_write_control,
arc_read_control, .read_control = arc_read_control,
arc_frob_control, .frob_control = arc_frob_control,
arc_read_status, .read_status = arc_read_status,
arc_enable_irq, .enable_irq = arc_enable_irq,
arc_disable_irq, .disable_irq = arc_disable_irq,
arc_data_forward, .data_forward = arc_data_forward,
arc_data_reverse, .data_reverse = arc_data_reverse,
arc_init_state, .init_state = arc_init_state,
arc_save_state, .save_state = arc_save_state,
arc_restore_state, .restore_state = arc_restore_state,
arc_inc_use_count, .epp_write_data = parport_ieee1284_epp_write_data,
arc_dec_use_count, .epp_read_data = parport_ieee1284_epp_read_data,
.epp_write_addr = parport_ieee1284_epp_write_addr,
.epp_read_addr = parport_ieee1284_epp_read_addr,
parport_ieee1284_epp_write_data, .ecp_write_data = parport_ieee1284_ecp_write_data,
parport_ieee1284_epp_read_data, .ecp_read_data = parport_ieee1284_ecp_read_data,
parport_ieee1284_epp_write_addr, .ecp_write_addr = parport_ieee1284_ecp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data, .compat_write_data = parport_ieee1284_write_compat,
parport_ieee1284_ecp_read_data, .nibble_read_data = parport_ieee1284_read_nibble,
parport_ieee1284_ecp_write_addr, .byte_read_data = parport_ieee1284_read_byte,
parport_ieee1284_write_compat, .owner = THIS_MODULE,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
}; };
/* --- Initialisation code -------------------------------- */ /* --- Initialisation code -------------------------------- */
...@@ -123,18 +108,24 @@ int parport_arc_init(void) ...@@ -123,18 +108,24 @@ int parport_arc_init(void)
{ {
/* Archimedes hardware provides only one port, at a fixed address */ /* Archimedes hardware provides only one port, at a fixed address */
struct parport *p; struct parport *p;
struct resource res;
char *fake_name = "parport probe");
if (check_region(PORT_BASE, 1)) res = request_region(PORT_BASE, 1, fake_name);
if (res == NULL)
return 0; return 0;
p = parport_register_port (PORT_BASE, IRQ_PRINTERACK, p = parport_register_port (PORT_BASE, IRQ_PRINTERACK,
PARPORT_DMA_NONE, &parport_arc_ops); PARPORT_DMA_NONE, &parport_arc_ops);
if (!p) if (!p) {
release_region(PORT_BASE, 1);
return 0; return 0;
}
p->modes = PARPORT_MODE_ARCSPP; p->modes = PARPORT_MODE_ARCSPP;
p->size = 1; p->size = 1;
rename_region(res, p->name);
printk(KERN_INFO "%s: Archimedes on-board port, using irq %d\n", printk(KERN_INFO "%s: Archimedes on-board port, using irq %d\n",
p->irq); p->irq);
......
...@@ -147,53 +147,40 @@ parport_atari_data_reverse(struct parport *p) ...@@ -147,53 +147,40 @@ parport_atari_data_reverse(struct parport *p)
#endif #endif
} }
static void
parport_atari_inc_use_count(void)
{
MOD_INC_USE_COUNT;
}
static void
parport_atari_dec_use_count(void)
{
MOD_DEC_USE_COUNT;
}
static struct parport_operations parport_atari_ops = { static struct parport_operations parport_atari_ops = {
parport_atari_write_data, .write_data = parport_atari_write_data,
parport_atari_read_data, .read_data = parport_atari_read_data,
parport_atari_write_control, .write_control = parport_atari_write_control,
parport_atari_read_control, .read_control = parport_atari_read_control,
parport_atari_frob_control, .frob_control = parport_atari_frob_control,
parport_atari_read_status, .read_status = parport_atari_read_status,
parport_atari_enable_irq, .enable_irq = parport_atari_enable_irq,
parport_atari_disable_irq, .disable_irq = parport_atari_disable_irq,
parport_atari_data_forward, .data_forward = parport_atari_data_forward,
parport_atari_data_reverse, .data_reverse = parport_atari_data_reverse,
parport_atari_init_state, .init_state = parport_atari_init_state,
parport_atari_save_state, .save_state = parport_atari_save_state,
parport_atari_restore_state, .restore_state = parport_atari_restore_state,
parport_atari_inc_use_count, .epp_write_data = parport_ieee1284_epp_write_data,
parport_atari_dec_use_count, .epp_read_data = parport_ieee1284_epp_read_data,
.epp_write_addr = parport_ieee1284_epp_write_addr,
.epp_read_addr = parport_ieee1284_epp_read_addr,
parport_ieee1284_epp_write_data, .ecp_write_data = parport_ieee1284_ecp_write_data,
parport_ieee1284_epp_read_data, .ecp_read_data = parport_ieee1284_ecp_read_data,
parport_ieee1284_epp_write_addr, .ecp_write_addr = parport_ieee1284_ecp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data, .compat_write_data = parport_ieee1284_write_compat,
parport_ieee1284_ecp_read_data, .nibble_read_data = parport_ieee1284_read_nibble,
parport_ieee1284_ecp_write_addr, .byte_read_data = parport_ieee1284_read_byte,
parport_ieee1284_write_compat, .owner = THIS_MODULE,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
}; };
......
...@@ -190,17 +190,6 @@ void parport_gsc_restore_state(struct parport *p, struct parport_state *s) ...@@ -190,17 +190,6 @@ void parport_gsc_restore_state(struct parport *p, struct parport_state *s)
parport_writeb (s->u.pc.ctr, CONTROL (p)); parport_writeb (s->u.pc.ctr, CONTROL (p));
} }
void parport_gsc_inc_use_count(void)
{
MOD_INC_USE_COUNT;
}
void parport_gsc_dec_use_count(void)
{
MOD_DEC_USE_COUNT;
}
struct parport_operations parport_gsc_ops = struct parport_operations parport_gsc_ops =
{ {
.write_data = parport_gsc_write_data, .write_data = parport_gsc_write_data,
...@@ -222,9 +211,6 @@ struct parport_operations parport_gsc_ops = ...@@ -222,9 +211,6 @@ struct parport_operations parport_gsc_ops =
.save_state = parport_gsc_save_state, .save_state = parport_gsc_save_state,
.restore_state = parport_gsc_restore_state, .restore_state = parport_gsc_restore_state,
.inc_use_count = parport_gsc_inc_use_count,
.dec_use_count = parport_gsc_dec_use_count,
.epp_write_data = parport_ieee1284_epp_write_data, .epp_write_data = parport_ieee1284_epp_write_data,
.epp_read_data = parport_ieee1284_epp_read_data, .epp_read_data = parport_ieee1284_epp_read_data,
.epp_write_addr = parport_ieee1284_epp_write_addr, .epp_write_addr = parport_ieee1284_epp_write_addr,
...@@ -237,6 +223,8 @@ struct parport_operations parport_gsc_ops = ...@@ -237,6 +223,8 @@ struct parport_operations parport_gsc_ops =
.compat_write_data = parport_ieee1284_write_compat, .compat_write_data = parport_ieee1284_write_compat,
.nibble_read_data = parport_ieee1284_read_nibble, .nibble_read_data = parport_ieee1284_read_nibble,
.byte_read_data = parport_ieee1284_read_byte, .byte_read_data = parport_ieee1284_read_byte,
.owner = THIS_MODULE,
}; };
/* --- Mode detection ------------------------------------- */ /* --- Mode detection ------------------------------------- */
......
...@@ -281,51 +281,40 @@ static void mfc3_restore_state(struct parport *p, struct parport_state *s) ...@@ -281,51 +281,40 @@ static void mfc3_restore_state(struct parport *p, struct parport_state *s)
pia(p)->cra |= PIA_DDR; pia(p)->cra |= PIA_DDR;
} }
static void mfc3_inc_use_count(void)
{
MOD_INC_USE_COUNT;
}
static void mfc3_dec_use_count(void)
{
MOD_DEC_USE_COUNT;
}
static struct parport_operations pp_mfc3_ops = { static struct parport_operations pp_mfc3_ops = {
mfc3_write_data, .write_data = mfc3_write_data,
mfc3_read_data, .read_data = mfc3_read_data,
mfc3_write_control, .write_control = mfc3_write_control,
mfc3_read_control, .read_control = mfc3_read_control,
mfc3_frob_control, .frob_control = mfc3_frob_control,
mfc3_read_status, .read_status = mfc3_read_status,
mfc3_enable_irq, .enable_irq = mfc3_enable_irq,
mfc3_disable_irq, .disable_irq = mfc3_disable_irq,
mfc3_data_forward, .data_forward = mfc3_data_forward,
mfc3_data_reverse, .data_reverse = mfc3_data_reverse,
mfc3_init_state, .init_state = mfc3_init_state,
mfc3_save_state, .save_state = mfc3_save_state,
mfc3_restore_state, .restore_state = mfc3_restore_state,
mfc3_inc_use_count, .epp_write_data = parport_ieee1284_epp_write_data,
mfc3_dec_use_count, .epp_read_data = parport_ieee1284_epp_read_data,
.epp_write_addr = parport_ieee1284_epp_write_addr,
.epp_read_addr = parport_ieee1284_epp_read_addr,
parport_ieee1284_epp_write_data, .ecp_write_data = parport_ieee1284_ecp_write_data,
parport_ieee1284_epp_read_data, .ecp_read_data = parport_ieee1284_ecp_read_data,
parport_ieee1284_epp_write_addr, .ecp_write_addr = parport_ieee1284_ecp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data, .compat_write_data = parport_ieee1284_write_compat,
parport_ieee1284_ecp_read_data, .nibble_read_data = parport_ieee1284_read_nibble,
parport_ieee1284_ecp_write_addr, .byte_read_data = parport_ieee1284_read_byte,
parport_ieee1284_write_compat, .owner = THIS_MODULE,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
}; };
/* ----------- Initialisation code --------------------------------- */ /* ----------- Initialisation code --------------------------------- */
......
...@@ -1232,57 +1232,41 @@ dump_parport_state ("fwd idle", port); ...@@ -1232,57 +1232,41 @@ dump_parport_state ("fwd idle", port);
* ****************************************** * ******************************************
*/ */
void parport_pc_inc_use_count(void)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
void parport_pc_dec_use_count(void)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
struct parport_operations parport_pc_ops = struct parport_operations parport_pc_ops =
{ {
parport_pc_write_data, .write_data = parport_pc_write_data,
parport_pc_read_data, .read_data = parport_pc_read_data,
parport_pc_write_control, .write_control = parport_pc_write_control,
parport_pc_read_control, .read_control = parport_pc_read_control,
parport_pc_frob_control, .frob_control = parport_pc_frob_control,
parport_pc_read_status, .read_status = parport_pc_read_status,
parport_pc_enable_irq, .enable_irq = parport_pc_enable_irq,
parport_pc_disable_irq, .disable_irq = parport_pc_disable_irq,
parport_pc_data_forward, .data_forward = parport_pc_data_forward,
parport_pc_data_reverse, .data_reverse = parport_pc_data_reverse,
parport_pc_init_state, .init_state = parport_pc_init_state,
parport_pc_save_state, .save_state = parport_pc_save_state,
parport_pc_restore_state, .restore_state = parport_pc_restore_state,
parport_pc_inc_use_count, .epp_write_data = parport_ieee1284_epp_write_data,
parport_pc_dec_use_count, .epp_read_data = parport_ieee1284_epp_read_data,
.epp_write_addr = parport_ieee1284_epp_write_addr,
.epp_read_addr = parport_ieee1284_epp_read_addr,
parport_ieee1284_epp_write_data, .ecp_write_data = parport_ieee1284_ecp_write_data,
parport_ieee1284_epp_read_data, .ecp_read_data = parport_ieee1284_ecp_read_data,
parport_ieee1284_epp_write_addr, .ecp_write_addr = parport_ieee1284_ecp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data, .compat_write_data = parport_ieee1284_write_compat,
parport_ieee1284_ecp_read_data, .nibble_read_data = parport_ieee1284_read_nibble,
parport_ieee1284_ecp_write_addr, .byte_read_data = parport_ieee1284_read_byte,
parport_ieee1284_write_compat, .owner = THIS_MODULE,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
}; };
#ifdef CONFIG_PARPORT_PC_SUPERIO #ifdef CONFIG_PARPORT_PC_SUPERIO
...@@ -2212,16 +2196,32 @@ struct parport *parport_pc_probe_port (unsigned long int base, ...@@ -2212,16 +2196,32 @@ struct parport *parport_pc_probe_port (unsigned long int base,
struct parport tmp; struct parport tmp;
struct parport *p = &tmp; struct parport *p = &tmp;
int probedirq = PARPORT_IRQ_NONE; int probedirq = PARPORT_IRQ_NONE;
if (check_region(base, 3)) return NULL; struct resource *base_res;
struct resource *ECR_res = NULL;
struct resource *EPP_res = NULL;
char *fake_name = "parport probe";
/*
* Chicken and Egg problem. request_region() wants the name of
* the owner, but this instance will not know that name until
* after the parport_register_port() call. Give request_region()
* a fake name until after parport_register_port(), then use
* rename_region() to set correct name.
*/
base_res = request_region(base, 3, fake_name);
if (base_res == NULL)
return NULL;
priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL); priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
if (!priv) { if (!priv) {
printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
release_region(base, 3);
return NULL; return NULL;
} }
ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
if (!ops) { if (!ops) {
printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n", printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n",
base); base);
release_region(base, 3);
kfree (priv); kfree (priv);
return NULL; return NULL;
} }
...@@ -2242,32 +2242,39 @@ struct parport *parport_pc_probe_port (unsigned long int base, ...@@ -2242,32 +2242,39 @@ struct parport *parport_pc_probe_port (unsigned long int base,
p->private_data = priv; p->private_data = priv;
p->physport = p; p->physport = p;
if (base_hi && !check_region(base_hi,3)) if (base_hi) {
ECR_res = request_region(base_hi, 3, fake_name);
if (ECR_res)
parport_ECR_present(p); parport_ECR_present(p);
}
if (base != 0x3bc) { if (base != 0x3bc) {
if (!check_region(base+0x3, 5)) { EPP_res = request_region(base+0x3, 5, fake_name);
if (EPP_res)
if (!parport_EPP_supported(p)) if (!parport_EPP_supported(p))
parport_ECPEPP_supported(p); parport_ECPEPP_supported(p);
} }
} if (!parport_SPP_supported (p))
if (!parport_SPP_supported (p)) {
/* No port. */ /* No port. */
kfree (priv); goto errout;
kfree (ops);
return NULL;
}
if (priv->ecr) if (priv->ecr)
parport_ECPPS2_supported(p); parport_ECPPS2_supported(p);
else else
parport_PS2_supported (p); parport_PS2_supported (p);
if (!(p = parport_register_port(base, PARPORT_IRQ_NONE, if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,
PARPORT_DMA_NONE, ops))) { PARPORT_DMA_NONE, ops)))
kfree (priv); goto errout;
kfree (ops);
return NULL; /*
} * Now the real name is known... Replace the fake name
* in the resources with the correct one.
*/
rename_region(base_res, p->name);
if (ECR_res)
rename_region(ECR_res, p->name);
if (EPP_res)
rename_region(EPP_res, p->name);
p->base_hi = base_hi; p->base_hi = base_hi;
p->modes = tmp.modes; p->modes = tmp.modes;
...@@ -2343,11 +2350,11 @@ struct parport *parport_pc_probe_port (unsigned long int base, ...@@ -2343,11 +2350,11 @@ struct parport *parport_pc_probe_port (unsigned long int base,
printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq); printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq);
parport_proc_register(p); parport_proc_register(p);
request_region (p->base, 3, p->name); /* If No ECP release the ports grabbed above. */
if (p->size > 3) if (ECR_res && (p->modes & PARPORT_MODE_ECP) == 0) {
request_region (p->base + 3, p->size - 3, p->name); release_region(base_hi, 3);
if (p->modes & PARPORT_MODE_ECP) ECR_res = NULL;
request_region (p->base_hi, 3, p->name); }
if (p->irq != PARPORT_IRQ_NONE) { if (p->irq != PARPORT_IRQ_NONE) {
if (request_irq (p->irq, parport_pc_interrupt, if (request_irq (p->irq, parport_pc_interrupt,
...@@ -2401,6 +2408,17 @@ struct parport *parport_pc_probe_port (unsigned long int base, ...@@ -2401,6 +2408,17 @@ struct parport *parport_pc_probe_port (unsigned long int base,
parport_announce_port (p); parport_announce_port (p);
return p; return p;
errout:
release_region(p->base, 3);
if (ECR_res)
release_region(base_hi, 3);
if (EPP_res)
release_region(base+0x3, 5);
kfree (priv);
kfree (ops);
return NULL;
} }
void parport_pc_unregister_port (struct parport *p) void parport_pc_unregister_port (struct parport *p)
...@@ -2437,9 +2455,11 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq, ...@@ -2437,9 +2455,11 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
int autodma) int autodma)
{ {
short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 }; short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 };
struct resource *base_res;
u32 ite8872set; u32 ite8872set;
u32 ite8872_lpt, ite8872_lpthi; u32 ite8872_lpt, ite8872_lpthi;
u8 ite8872_irq, type; u8 ite8872_irq, type;
char *fake_name = "parport probe";
int irq; int irq;
int i; int i;
...@@ -2447,7 +2467,8 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq, ...@@ -2447,7 +2467,8 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
// make sure which one chip // make sure which one chip
for(i = 0; i < 5; i++) { for(i = 0; i < 5; i++) {
if (check_region (inta_addr[i], 0x8) >= 0) { base_res = request_region(inta_addr[i], 0x8, fake_name);
if (base_res) {
int test; int test;
pci_write_config_dword (pdev, 0x60, pci_write_config_dword (pdev, 0x60,
0xe7000000 | inta_addr[i]); 0xe7000000 | inta_addr[i]);
...@@ -2455,6 +2476,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq, ...@@ -2455,6 +2476,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
0x00000000 | inta_addr[i]); 0x00000000 | inta_addr[i]);
test = inb (inta_addr[i]); test = inb (inta_addr[i]);
if (test != 0xff) break; if (test != 0xff) break;
release_region(inta_addr[i], 0x8);
} }
} }
if(i >= 5) { if(i >= 5) {
...@@ -2515,6 +2537,10 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq, ...@@ -2515,6 +2537,10 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
if (autoirq != PARPORT_IRQ_AUTO) if (autoirq != PARPORT_IRQ_AUTO)
irq = PARPORT_IRQ_NONE; irq = PARPORT_IRQ_NONE;
/*
* Release the resource so that parport_pc_probe_port can get it.
*/
release_resource(base_res);
if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi, if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
irq, PARPORT_DMA_NONE, NULL)) { irq, PARPORT_DMA_NONE, NULL)) {
printk (KERN_INFO printk (KERN_INFO
......
...@@ -249,56 +249,41 @@ static void parport_sunbpp_restore_state(struct parport *p, struct parport_state ...@@ -249,56 +249,41 @@ static void parport_sunbpp_restore_state(struct parport *p, struct parport_state
parport_sunbpp_write_control(p, s->u.pc.ctr); parport_sunbpp_write_control(p, s->u.pc.ctr);
} }
static void parport_sunbpp_inc_use_count(void)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
static void parport_sunbpp_dec_use_count(void)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations parport_sunbpp_ops = static struct parport_operations parport_sunbpp_ops =
{ {
parport_sunbpp_write_data, .write_data = parport_sunbpp_write_data,
parport_sunbpp_read_data, .read_data = parport_sunbpp_read_data,
parport_sunbpp_write_control, .write_control = parport_sunbpp_write_control,
parport_sunbpp_read_control, .read_control = parport_sunbpp_read_control,
parport_sunbpp_frob_control, .frob_control = parport_sunbpp_frob_control,
parport_sunbpp_read_status, .read_status = parport_sunbpp_read_status,
parport_sunbpp_enable_irq, .enable_irq = parport_sunbpp_enable_irq,
parport_sunbpp_disable_irq, .disable_irq = parport_sunbpp_disable_irq,
parport_sunbpp_data_forward, .data_forward = parport_sunbpp_data_forward,
parport_sunbpp_data_reverse, .data_reverse = parport_sunbpp_data_reverse,
parport_sunbpp_init_state, .init_state = parport_sunbpp_init_state,
parport_sunbpp_save_state, .save_state = parport_sunbpp_save_state,
parport_sunbpp_restore_state, .restore_state = parport_sunbpp_restore_state,
parport_sunbpp_inc_use_count, .epp_write_data = parport_ieee1284_epp_write_data,
parport_sunbpp_dec_use_count, .epp_read_data = parport_ieee1284_epp_read_data,
.epp_write_addr = parport_ieee1284_epp_write_addr,
.epp_read_addr = parport_ieee1284_epp_read_addr,
parport_ieee1284_epp_write_data, .ecp_write_data = parport_ieee1284_ecp_write_data,
parport_ieee1284_epp_read_data, .ecp_read_data = parport_ieee1284_ecp_read_data,
parport_ieee1284_epp_write_addr, .ecp_write_addr = parport_ieee1284_ecp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data, .compat_write_data = parport_ieee1284_write_compat,
parport_ieee1284_ecp_read_data, .nibble_read_data = parport_ieee1284_read_nibble,
parport_ieee1284_ecp_write_addr, .byte_read_data = parport_ieee1284_read_byte,
parport_ieee1284_write_compat, .owner = THIS_MODULE,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
}; };
static int __init init_one_port(struct sbus_dev *sdev) static int __init init_one_port(struct sbus_dev *sdev)
......
...@@ -55,37 +55,44 @@ static unsigned char dead_frob_lines (struct parport *p, unsigned char b, ...@@ -55,37 +55,44 @@ static unsigned char dead_frob_lines (struct parport *p, unsigned char b,
static void dead_onearg (struct parport *p){} static void dead_onearg (struct parport *p){}
static void dead_initstate (struct pardevice *d, struct parport_state *s) { } static void dead_initstate (struct pardevice *d, struct parport_state *s) { }
static void dead_state (struct parport *p, struct parport_state *s) { } static void dead_state (struct parport *p, struct parport_state *s) { }
static void dead_noargs (void) { }
static size_t dead_write (struct parport *p, const void *b, size_t l, int f) static size_t dead_write (struct parport *p, const void *b, size_t l, int f)
{ return 0; } { return 0; }
static size_t dead_read (struct parport *p, void *b, size_t l, int f) static size_t dead_read (struct parport *p, void *b, size_t l, int f)
{ return 0; } { return 0; }
static struct parport_operations dead_ops = { static struct parport_operations dead_ops = {
dead_write_lines, /* data */ .write_data = dead_write_lines, /* data */
dead_read_lines, .read_data = dead_read_lines,
dead_write_lines, /* control */
dead_read_lines, .write_control = dead_write_lines, /* control */
dead_frob_lines, .read_control = dead_read_lines,
dead_read_lines, /* status */ .frob_control = dead_frob_lines,
dead_onearg, /* enable_irq */
dead_onearg, /* disable_irq */ .read_status = dead_read_lines, /* status */
dead_onearg, /* data_forward */
dead_onearg, /* data_reverse */ .enable_irq = dead_onearg, /* enable_irq */
dead_initstate, /* init_state */ .disable_irq = dead_onearg, /* disable_irq */
dead_state,
dead_state, .data_forward = dead_onearg, /* data_forward */
dead_noargs, /* xxx_use_count */ .data_reverse = dead_onearg, /* data_reverse */
dead_noargs,
dead_write, /* epp */ .init_state = dead_initstate, /* init_state */
dead_read, .save_state = dead_state,
dead_write, .restore_state = dead_state,
dead_read,
dead_write, /* ecp */ .epp_write_data = dead_write, /* epp */
dead_read, .epp_read_data = dead_read,
dead_write, .epp_write_addr = dead_write,
dead_write, /* compat */ .epp_read_addr = dead_read,
dead_read, /* nibble */
dead_read /* byte */ .ecp_write_data = dead_write, /* ecp */
.ecp_read_data = dead_read,
.ecp_write_addr = dead_write,
.compat_write_data = dead_write, /* compat */
.nibble_read_data = dead_read, /* nibble */
.byte_read_data = dead_read, /* byte */
.owner = NULL,
}; };
/* Call attach(port) for each registered driver. */ /* Call attach(port) for each registered driver. */
...@@ -390,25 +397,6 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, ...@@ -390,25 +397,6 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
return NULL; return NULL;
} }
/* Search for the lowest free parport number. */
spin_lock_irq (&parportlist_lock);
for (portnum = 0; ; portnum++) {
struct parport *itr = portlist;
while (itr) {
if (itr->number == portnum)
/* No good, already used. */
break;
else
itr = itr->next;
}
if (itr == NULL)
/* Got to the end of the list. */
break;
}
spin_unlock_irq (&parportlist_lock);
/* Init our structure */ /* Init our structure */
memset(tmp, 0, sizeof(struct parport)); memset(tmp, 0, sizeof(struct parport));
tmp->base = base; tmp->base = base;
...@@ -420,7 +408,6 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, ...@@ -420,7 +408,6 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
tmp->devices = tmp->cad = NULL; tmp->devices = tmp->cad = NULL;
tmp->flags = 0; tmp->flags = 0;
tmp->ops = ops; tmp->ops = ops;
tmp->portnum = tmp->number = portnum;
tmp->physport = tmp; tmp->physport = tmp;
memset (tmp->probe_info, 0, 5 * sizeof (struct parport_device_info)); memset (tmp->probe_info, 0, 5 * sizeof (struct parport_device_info));
tmp->cad_lock = RW_LOCK_UNLOCKED; tmp->cad_lock = RW_LOCK_UNLOCKED;
...@@ -438,9 +425,32 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, ...@@ -438,9 +425,32 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
kfree(tmp); kfree(tmp);
return NULL; return NULL;
} }
/* Search for the lowest free parport number. */
spin_lock_irq (&parportlist_lock);
for (portnum = 0; ; portnum++) {
struct parport *itr = portlist;
while (itr) {
if (itr->number == portnum)
/* No good, already used. */
break;
else
itr = itr->next;
}
if (itr == NULL)
/* Got to the end of the list. */
break;
}
/*
* Now that the portnum is known finish doing the Init.
*/
tmp->portnum = tmp->number = portnum;
sprintf(name, "parport%d", portnum); sprintf(name, "parport%d", portnum);
tmp->name = name; tmp->name = name;
/* /*
* Chain the entry to our list. * Chain the entry to our list.
* *
...@@ -448,8 +458,6 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, ...@@ -448,8 +458,6 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
* to clear irq on the local CPU. -arca * to clear irq on the local CPU. -arca
*/ */
spin_lock(&parportlist_lock);
/* We are locked against anyone else performing alterations, but /* We are locked against anyone else performing alterations, but
* because of parport_enumerate people can still _read_ the list * because of parport_enumerate people can still _read_ the list
* while we are changing it; so be careful.. * while we are changing it; so be careful..
...@@ -664,8 +672,10 @@ parport_register_device(struct parport *port, const char *name, ...@@ -664,8 +672,10 @@ parport_register_device(struct parport *port, const char *name,
kmalloc. To be absolutely safe, we have to require that kmalloc. To be absolutely safe, we have to require that
our caller doesn't sleep in between parport_enumerate and our caller doesn't sleep in between parport_enumerate and
parport_register_device.. */ parport_register_device.. */
inc_parport_count(); if (!try_module_get(port->ops->owner)) {
port->ops->inc_use_count(); return NULL;
}
parport_get_port (port); parport_get_port (port);
tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL); tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL);
...@@ -736,9 +746,9 @@ parport_register_device(struct parport *port, const char *name, ...@@ -736,9 +746,9 @@ parport_register_device(struct parport *port, const char *name,
out_free_pardevice: out_free_pardevice:
kfree (tmp); kfree (tmp);
out: out:
dec_parport_count();
port->ops->dec_use_count();
parport_put_port (port); parport_put_port (port);
module_put(port->ops->owner);
return NULL; return NULL;
} }
...@@ -801,8 +811,7 @@ void parport_unregister_device(struct pardevice *dev) ...@@ -801,8 +811,7 @@ void parport_unregister_device(struct pardevice *dev)
kfree(dev->state); kfree(dev->state);
kfree(dev); kfree(dev);
dec_parport_count(); module_put(port->ops->owner);
port->ops->dec_use_count();
parport_put_port (port); parport_put_port (port);
/* Yes, that's right, someone _could_ still have a pointer to /* Yes, that's right, someone _could_ still have a pointer to
......
...@@ -166,9 +166,6 @@ struct parport_operations { ...@@ -166,9 +166,6 @@ struct parport_operations {
void (*save_state)(struct parport *, struct parport_state *); void (*save_state)(struct parport *, struct parport_state *);
void (*restore_state)(struct parport *, struct parport_state *); void (*restore_state)(struct parport *, struct parport_state *);
void (*inc_use_count)(void);
void (*dec_use_count)(void);
/* Block read/write */ /* Block read/write */
size_t (*epp_write_data) (struct parport *port, const void *buf, size_t (*epp_write_data) (struct parport *port, const void *buf,
size_t len, int flags); size_t len, int flags);
...@@ -192,6 +189,7 @@ struct parport_operations { ...@@ -192,6 +189,7 @@ struct parport_operations {
size_t len, int flags); size_t len, int flags);
size_t (*byte_read_data) (struct parport *port, void *buf, size_t (*byte_read_data) (struct parport *port, void *buf,
size_t len, int flags); size_t len, int flags);
struct module *owner;
}; };
struct parport_device_info { struct parport_device_info {
...@@ -541,9 +539,6 @@ extern int parport_device_proc_unregister(struct pardevice *device); ...@@ -541,9 +539,6 @@ extern int parport_device_proc_unregister(struct pardevice *device);
extern int parport_default_proc_register(void); extern int parport_default_proc_register(void);
extern int parport_default_proc_unregister(void); extern int parport_default_proc_unregister(void);
extern void dec_parport_count(void);
extern void inc_parport_count(void);
/* If PC hardware is the only type supported, we can optimise a bit. */ /* If PC hardware is the only type supported, we can optimise a bit. */
#if (defined(CONFIG_PARPORT_PC) || defined(CONFIG_PARPORT_PC_MODULE)) && !(defined(CONFIG_PARPORT_ARC) || defined(CONFIG_PARPORT_ARC_MODULE)) && !(defined(CONFIG_PARPORT_AMIGA) || defined(CONFIG_PARPORT_AMIGA_MODULE)) && !(defined(CONFIG_PARPORT_MFC3) || defined(CONFIG_PARPORT_MFC3_MODULE)) && !(defined(CONFIG_PARPORT_ATARI) || defined(CONFIG_PARPORT_ATARI_MODULE)) && !(defined(CONFIG_USB_USS720) || defined(CONFIG_USB_USS720_MODULE)) && !(defined(CONFIG_PARPORT_SUNBPP) || defined(CONFIG_PARPORT_SUNBPP_MODULE)) && !defined(CONFIG_PARPORT_OTHER) #if (defined(CONFIG_PARPORT_PC) || defined(CONFIG_PARPORT_PC_MODULE)) && !(defined(CONFIG_PARPORT_ARC) || defined(CONFIG_PARPORT_ARC_MODULE)) && !(defined(CONFIG_PARPORT_AMIGA) || defined(CONFIG_PARPORT_AMIGA_MODULE)) && !(defined(CONFIG_PARPORT_MFC3) || defined(CONFIG_PARPORT_MFC3_MODULE)) && !(defined(CONFIG_PARPORT_ATARI) || defined(CONFIG_PARPORT_ATARI_MODULE)) && !(defined(CONFIG_USB_USS720) || defined(CONFIG_USB_USS720_MODULE)) && !(defined(CONFIG_PARPORT_SUNBPP) || defined(CONFIG_PARPORT_SUNBPP_MODULE)) && !defined(CONFIG_PARPORT_OTHER)
......
...@@ -215,10 +215,6 @@ extern void parport_pc_save_state(struct parport *p, struct parport_state *s); ...@@ -215,10 +215,6 @@ extern void parport_pc_save_state(struct parport *p, struct parport_state *s);
extern void parport_pc_restore_state(struct parport *p, struct parport_state *s); extern void parport_pc_restore_state(struct parport *p, struct parport_state *s);
extern void parport_pc_inc_use_count(void);
extern void parport_pc_dec_use_count(void);
/* PCMCIA code will want to get us to look at a port. Provide a mechanism. */ /* PCMCIA code will want to get us to look at a port. Provide a mechanism. */
extern struct parport *parport_pc_probe_port (unsigned long base, extern struct parport *parport_pc_probe_port (unsigned long base,
unsigned long base_hi, unsigned long base_hi,
......
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