Skip to content

Commit 27ee896

Browse files
committed
Merge branch 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
* 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: pcmcia: fix error handling in cm4000_cs.c drivers/pcmcia: Add missing local_irq_restore serial_cs: MD55x support (PCMCIA GPRS/EDGE modem) (kernel 2.6.33) pcmcia: avoid late calls to pccard_validate_cis pcmcia: fix ioport size calculation in rsrc_nonstatic pcmcia: re-start on MFC override pcmcia: fix io_probe due to parent (PCI) resources pcmcia: use previously assigned IRQ for all card functions
2 parents ac8bf56 + 07a7141 commit 27ee896

File tree

7 files changed

+55
-23
lines changed

7 files changed

+55
-23
lines changed

drivers/char/pcmcia/cm4000_cs.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
10261026

10271027
xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */
10281028
/* last check before exit */
1029-
if (!io_detect_cm4000(iobase, dev))
1030-
count = -ENODEV;
1029+
if (!io_detect_cm4000(iobase, dev)) {
1030+
rc = -ENODEV;
1031+
goto release_io;
1032+
}
10311033

10321034
if (test_bit(IS_INVREV, &dev->flags) && count > 0)
10331035
str_invert_revert(dev->rbuf, count);
10341036

10351037
if (copy_to_user(buf, dev->rbuf, count))
1036-
return -EFAULT;
1038+
rc = -EFAULT;
10371039

10381040
release_io:
10391041
clear_bit(LOCK_IO, &dev->flags);

drivers/pcmcia/cistpl.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
14841484
if (!s)
14851485
return -EINVAL;
14861486

1487+
if (s->functions) {
1488+
WARN_ON(1);
1489+
return -EINVAL;
1490+
}
1491+
14871492
/* We do not want to validate the CIS cache... */
14881493
mutex_lock(&s->ops_mutex);
14891494
destroy_cis_cache(s);
@@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
16391644
count = 0;
16401645
else {
16411646
struct pcmcia_socket *s;
1642-
unsigned int chains;
1647+
unsigned int chains = 1;
16431648

16441649
if (off + count > size)
16451650
count = size - off;
@@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
16481653

16491654
if (!(s->state & SOCKET_PRESENT))
16501655
return -ENODEV;
1651-
if (pccard_validate_cis(s, &chains))
1656+
if (!s->functions && pccard_validate_cis(s, &chains))
16521657
return -EIO;
16531658
if (!chains)
16541659
return -ENODATA;

drivers/pcmcia/db1xxx_ss.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,10 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
166166

167167
ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
168168
IRQF_DISABLED, "pcmcia_insert", sock);
169-
if (ret)
169+
if (ret) {
170+
local_irq_restore(flags);
170171
goto out1;
172+
}
171173

172174
ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq,
173175
IRQF_DISABLED, "pcmcia_eject", sock);

drivers/pcmcia/ds.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -687,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s)
687687
new_funcs = mfc.nfn;
688688
else
689689
new_funcs = 1;
690-
if (old_funcs > new_funcs) {
690+
if (old_funcs != new_funcs) {
691+
/* we need to re-start */
691692
pcmcia_card_remove(s, NULL);
692693
pcmcia_card_add(s);
693-
} else if (new_funcs > old_funcs) {
694-
s->functions = new_funcs;
695-
pcmcia_device_add(s, 1);
696694
}
697695
}
698696

@@ -728,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
728726
struct pcmcia_socket *s = dev->socket;
729727
const struct firmware *fw;
730728
int ret = -ENOMEM;
729+
cistpl_longlink_mfc_t mfc;
730+
int old_funcs, new_funcs = 1;
731731

732732
if (!filename)
733733
return -EINVAL;
@@ -750,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
750750
goto release;
751751
}
752752

753+
/* we need to re-start if the number of functions changed */
754+
old_funcs = s->functions;
755+
if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
756+
&mfc))
757+
new_funcs = mfc.nfn;
758+
759+
if (old_funcs != new_funcs)
760+
ret = -EBUSY;
753761

754762
/* update information */
755763
pcmcia_device_query(dev);
@@ -858,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
858866
if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
859867
dev_dbg(&dev->dev, "device needs a fake CIS\n");
860868
if (!dev->socket->fake_cis)
861-
pcmcia_load_firmware(dev, did->cisfile);
862-
863-
if (!dev->socket->fake_cis)
864-
return 0;
869+
if (pcmcia_load_firmware(dev, did->cisfile))
870+
return 0;
865871
}
866872

867873
if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {

drivers/pcmcia/pcmcia_resource.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,12 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
755755
else
756756
printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
757757

758-
#ifdef CONFIG_PCMCIA_PROBE
759-
760-
if (s->irq.AssignedIRQ != 0) {
761-
/* If the interrupt is already assigned, it must be the same */
758+
/* If the interrupt is already assigned, it must be the same */
759+
if (s->irq.AssignedIRQ != 0)
762760
irq = s->irq.AssignedIRQ;
763-
} else {
761+
762+
#ifdef CONFIG_PCMCIA_PROBE
763+
if (!irq) {
764764
int try;
765765
u32 mask = s->irq_mask;
766766
void *data = p_dev; /* something unique to this device */

drivers/pcmcia/rsrc_nonstatic.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
214214
return;
215215
}
216216
for (i = base, most = 0; i < base+num; i += 8) {
217-
res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
217+
res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
218218
if (!res)
219219
continue;
220220
hole = inb(i);
@@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
231231

232232
bad = any = 0;
233233
for (i = base; i < base+num; i += 8) {
234-
res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
235-
if (!res)
234+
res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
235+
if (!res) {
236+
if (!any)
237+
printk(" excluding");
238+
if (!bad)
239+
bad = any = i;
236240
continue;
241+
}
237242
for (j = 0; j < 8; j++)
238243
if (inb(i+j) != most)
239244
break;
@@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
253258
}
254259
if (bad) {
255260
if ((num > 16) && (bad == base) && (i == base+num)) {
261+
sub_interval(&s_data->io_db, bad, i-bad);
256262
printk(" nothing: probe failed.\n");
257263
return;
258264
} else {
@@ -804,7 +810,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
804810
static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
805811
{
806812
struct socket_data *data = s->resource_data;
807-
unsigned long size = end - start + 1;
813+
unsigned long size;
808814
int ret = 0;
809815

810816
#if defined(CONFIG_X86)
@@ -814,6 +820,8 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
814820
start = 0x100;
815821
#endif
816822

823+
size = end - start + 1;
824+
817825
if (end < start)
818826
return -EINVAL;
819827

drivers/serial/serial_cs.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ struct serial_cfg_mem {
105105
* manfid 0x0160, 0x0104
106106
* This card appears to have a 14.7456MHz clock.
107107
*/
108+
/* Generic Modem: MD55x (GPRS/EDGE) have
109+
* Elan VPU16551 UART with 14.7456MHz oscillator
110+
* manfid 0x015D, 0x4C45
111+
*/
108112
static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
109113
{
110114
port->uartclk = 14745600;
@@ -195,6 +199,11 @@ static const struct serial_quirk quirks[] = {
195199
.prodid = 0x0104,
196200
.multi = -1,
197201
.setup = quirk_setup_brainboxes_0104,
202+
}, {
203+
.manfid = 0x015D,
204+
.prodid = 0x4C45,
205+
.multi = -1,
206+
.setup = quirk_setup_brainboxes_0104,
198207
}, {
199208
.manfid = MANFID_IBM,
200209
.prodid = ~0,

0 commit comments

Comments
 (0)