--- linux-2.4.0-test13-pre4/include/linux/parport.h Mon Dec 11 12:50:09 2000 +++ linux/include/linux/parport.h Sun Dec 24 01:44:12 2000 @@ -34,24 +34,6 @@ #define PARPORT_STATUS_ACK 0x40 #define PARPORT_STATUS_BUSY 0x80 -/* Type classes for Plug-and-Play probe. */ -typedef enum { - PARPORT_CLASS_LEGACY = 0, /* Non-IEEE1284 device */ - PARPORT_CLASS_PRINTER, - PARPORT_CLASS_MODEM, - PARPORT_CLASS_NET, - PARPORT_CLASS_HDC, /* Hard disk controller */ - PARPORT_CLASS_PCMCIA, - PARPORT_CLASS_MEDIA, /* Multimedia device */ - PARPORT_CLASS_FDC, /* Floppy disk controller */ - PARPORT_CLASS_PORTS, - PARPORT_CLASS_SCANNER, - PARPORT_CLASS_DIGCAM, - PARPORT_CLASS_OTHER, /* Anything else */ - PARPORT_CLASS_UNSPEC, /* No CLS field in ID */ - PARPORT_CLASS_SCSIADAPTER -} parport_device_class; - /* The "modes" entry in parport is a bit field representing the capabilities of the hardware. */ #define PARPORT_MODE_PCSPP (1<<0) /* IBM PC registers available. */ @@ -91,6 +73,10 @@ /* Flags for block transfer operations. */ #define PARPORT_EPP_FAST (1<<0) /* Unreliable counts. */ +struct parport_device_id { + const char *pattern; +}; + /* The rest is for the kernel only */ #ifdef __KERNEL__ @@ -191,15 +177,6 @@ size_t len, int flags); }; -struct parport_device_info { - parport_device_class class; - const char *class_name; - const char *mfr; - const char *model; - const char *cmdset; - const char *description; -}; - /* Each device can have two callback functions: * 1) a preemption function, called by the resource manager to request * that the driver relinquish control of the port. The driver should @@ -296,7 +273,7 @@ unsigned int flags; void *sysctl_table; - struct parport_device_info probe_info[5]; /* 0-3 + non-IEEE1284.3 */ + unsigned char *probe_strings[5]; /* 0-3 + non-IEEE1284.3 */ struct ieee1284_info ieee1284; struct parport_operations *ops; @@ -498,22 +475,14 @@ struct pt_regs *), int flags, void *handle); extern void parport_close (struct pardevice *dev); -extern ssize_t parport_device_id (int devnum, char *buffer, size_t len); +extern ssize_t parport_get_id (int devnum, char **buf_out); +extern const struct parport_device_id *parport_match_id( + const char *probe_str, const struct parport_device_id *ids); extern int parport_device_num (int parport, int mux, int daisy); extern int parport_device_coords (int devnum, int *parport, int *mux, int *daisy); extern void parport_daisy_deselect_all (struct parport *port); extern int parport_daisy_select (struct parport *port, int daisy, int mode); - -/* For finding devices based on their device ID. Example usage: - int devnum = -1; - while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM, devnum)) != -1) { - struct pardevice *dev = parport_open (devnum, ...); - ... - } -*/ -extern int parport_find_device (const char *mfg, const char *mdl, int from); -extern int parport_find_class (parport_device_class cls, int from); /* Lowlevel drivers _can_ call this support function to handle irqs. */ extern __inline__ void parport_generic_irq(int irq, struct parport *port, diff -r -u linux-2.4.0-test13-pre4/drivers/parport/daisy.c linux/drivers/parport/daisy.c --- linux-2.4.0-test13-pre4/drivers/parport/daisy.c Fri Jul 21 14:21:58 2000 +++ linux/drivers/parport/daisy.c Sun Dec 24 01:36:11 2000 @@ -140,12 +140,8 @@ add_dev (numdevs++, port, -1); /* Find out the legacy device's IEEE 1284 device ID. */ - deviceid = kmalloc (1000, GFP_KERNEL); - if (deviceid) { - if (parport_device_id (numdevs - 1, deviceid, 1000) > 2) - detected++; - - kfree (deviceid); + if (parport_get_id (numdevs - 1, &deviceid) > 2) { + detected++; } return detected; @@ -189,8 +185,7 @@ * * This function is similar to parport_register_device(), except * that it locates a device by its number rather than by the port - * it is attached to. See parport_find_device() and - * parport_find_class(). + * it is attached to. * * All parameters except for @devnum are the same as for * parport_register_device(). The return value is the same as @@ -493,98 +488,9 @@ detected); /* Ask the new devices to introduce themselves. */ - deviceid = kmalloc (1000, GFP_KERNEL); - if (!deviceid) return 0; - for (daisy = 0; thisdev < numdevs; thisdev++, daisy++) - parport_device_id (thisdev, deviceid, 1000); + parport_get_id (thisdev, &deviceid); - kfree (deviceid); return detected; } -/* Find a device with a particular manufacturer and model string, - starting from a given device number. Like the PCI equivalent, - 'from' itself is skipped. */ - -/** - * parport_find_device - find a specific device - * @mfg: required manufacturer string - * @mdl: required model string - * @from: previous device number found in search, or %NULL for - * new search - * - * This walks through the list of parallel port devices looking - * for a device whose 'MFG' string matches @mfg and whose 'MDL' - * string matches @mdl in their IEEE 1284 Device ID. - * - * When a device is found matching those requirements, its device - * number is returned; if there is no matching device, a negative - * value is returned. - * - * A new search it initiated by passing %NULL as the @from - * argument. If @from is not %NULL, the search continues from - * that device. - **/ - -int parport_find_device (const char *mfg, const char *mdl, int from) -{ - struct daisydev *d = topology; /* sorted by devnum */ - - /* Find where to start. */ - while (d && d->devnum <= from) - d = d->next; - - /* Search. */ - while (d) { - struct parport_device_info *info; - info = &d->port->probe_info[1 + d->daisy]; - if ((!mfg || !strcmp (mfg, info->mfr)) && - (!mdl || !strcmp (mdl, info->model))) - break; - - d = d->next; - } - - if (d) - return d->devnum; - - return -1; -} - -/** - * parport_find_class - find a device in a specified class - * @cls: required class - * @from: previous device number found in search, or %NULL for - * new search - * - * This walks through the list of parallel port devices looking - * for a device whose 'CLS' string matches @cls in their IEEE - * 1284 Device ID. - * - * When a device is found matching those requirements, its device - * number is returned; if there is no matching device, a negative - * value is returned. - * - * A new search it initiated by passing %NULL as the @from - * argument. If @from is not %NULL, the search continues from - * that device. - **/ - -int parport_find_class (parport_device_class cls, int from) -{ - struct daisydev *d = topology; /* sorted by devnum */ - - /* Find where to start. */ - while (d && d->devnum <= from) - d = d->next; - - /* Search. */ - while (d && d->port->probe_info[1 + d->daisy].class != cls) - d = d->next; - - if (d) - return d->devnum; - - return -1; -} diff -r -u linux-2.4.0-test13-pre4/drivers/parport/init.c linux/drivers/parport/init.c --- linux-2.4.0-test13-pre4/drivers/parport/init.c Wed Jul 12 16:24:33 2000 +++ linux/drivers/parport/init.c Sun Dec 24 01:36:11 2000 @@ -214,14 +214,13 @@ #ifdef CONFIG_PARPORT_1284 EXPORT_SYMBOL(parport_open); EXPORT_SYMBOL(parport_close); -EXPORT_SYMBOL(parport_device_id); +EXPORT_SYMBOL(parport_get_id); +EXPORT_SYMBOL(parport_match_id); EXPORT_SYMBOL(parport_device_num); EXPORT_SYMBOL(parport_device_coords); EXPORT_SYMBOL(parport_daisy_deselect_all); EXPORT_SYMBOL(parport_daisy_select); EXPORT_SYMBOL(parport_daisy_init); -EXPORT_SYMBOL(parport_find_device); -EXPORT_SYMBOL(parport_find_class); #endif void inc_parport_count(void) diff -r -u linux-2.4.0-test13-pre4/drivers/parport/probe.c linux/drivers/parport/probe.c --- linux-2.4.0-test13-pre4/drivers/parport/probe.c Thu Feb 24 10:08:32 2000 +++ linux/drivers/parport/probe.c Sun Dec 24 02:07:01 2000 @@ -7,132 +7,13 @@ #include #include +#include #include -static struct { - char *token; - char *descr; -} classes[] = { - { "", "Legacy device" }, - { "PRINTER", "Printer" }, - { "MODEM", "Modem" }, - { "NET", "Network device" }, - { "HDC", "Hard disk" }, - { "PCMCIA", "PCMCIA" }, - { "MEDIA", "Multimedia device" }, - { "FDC", "Floppy disk" }, - { "PORTS", "Ports" }, - { "SCANNER", "Scanner" }, - { "DIGICAM", "Digital camera" }, - { "", "Unknown device" }, - { "", "Unspecified" }, - { "SCSIADAPTER", "SCSI adapter" }, - { NULL, NULL } -}; - -static void pretty_print(struct parport *port, int device) -{ - struct parport_device_info *info = &port->probe_info[device + 1]; - - printk(KERN_INFO "%s", port->name); - - if (device >= 0) - printk (" (addr %d)", device); - - printk (": %s", classes[info->class].descr); - if (info->class) - printk(", %s %s", info->mfr, info->model); - - printk("\n"); -} - -static char *strdup(char *str) -{ - int n = strlen(str)+1; - char *s = kmalloc(n, GFP_KERNEL); - if (!s) return NULL; - return strcpy(s, str); -} - -static void parse_data(struct parport *port, int device, char *str) -{ - char *txt = kmalloc(strlen(str)+1, GFP_KERNEL); - char *p = txt, *q; - int guessed_class = PARPORT_CLASS_UNSPEC; - struct parport_device_info *info = &port->probe_info[device + 1]; - - if (!txt) { - printk("%s probe: memory squeeze\n", port->name); - return; - } - strcpy(txt, str); - while (p) { - char *sep; - q = strchr(p, ';'); - if (q) *q = 0; - sep = strchr(p, ':'); - if (sep) { - char *u = p; - *(sep++) = 0; - while (*u) { - *u = toupper(*u); - u++; - } - if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) { - if (info->mfr) - kfree (info->mfr); - info->mfr = strdup(sep); - } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) { - if (info->model) - kfree (info->model); - info->model = strdup(sep); - } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) { - int i; - if (info->class_name) - kfree (info->class_name); - info->class_name = strdup(sep); - for (u = sep; *u; u++) - *u = toupper(*u); - for (i = 0; classes[i].token; i++) { - if (!strcmp(classes[i].token, sep)) { - info->class = i; - goto rock_on; - } - } - printk(KERN_WARNING "%s probe: warning, class '%s' not understood.\n", port->name, sep); - info->class = PARPORT_CLASS_OTHER; - } else if (!strcmp(p, "CMD") || - !strcmp(p, "COMMAND SET")) { - if (info->cmdset) - kfree (info->cmdset); - info->cmdset = strdup(sep); - /* if it speaks printer language, it's - probably a printer */ - if (strstr(sep, "PJL") || strstr(sep, "PCL")) - guessed_class = PARPORT_CLASS_PRINTER; - } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) { - if (info->description) - kfree (info->description); - info->description = strdup(sep); - } - } - rock_on: - if (q) p = q+1; else p=NULL; - } - - /* If the device didn't tell us its class, maybe we have managed to - guess one from the things it did say. */ - if (info->class == PARPORT_CLASS_UNSPEC) - info->class = guessed_class; - - pretty_print (port, device); - - kfree(txt); -} - /* Get Std 1284 Device ID. */ -ssize_t parport_device_id (int devnum, char *buffer, size_t len) +ssize_t parport_get_id (int devnum, char **buf_out) { + char *buffer; ssize_t retval = -ENXIO; struct pardevice *dev = parport_open (devnum, "Device ID probe", NULL, NULL, NULL, 0, NULL); @@ -146,9 +27,8 @@ parport_negotiate (dev->port, IEEE1284_MODE_COMPAT); retval = parport_negotiate (dev->port, IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID); - if (!retval) { - int idlen; + int len; unsigned char length[2]; /* First two bytes are MSB,LSB of inclusive length. */ @@ -156,53 +36,170 @@ if (retval != 2) goto end_id; - idlen = (length[0] << 8) + length[1] - 2; - if (idlen < len) - len = idlen; - retval = parport_read (dev->port, buffer, len); + len = (length[0] << 8) + length[1]; - if (retval != len) - printk (KERN_DEBUG "%s: only read %Zd of %Zd ID bytes\n", + /* Some printer manufacturers mistakenly believe that + the length field is supposed to be _exclusive_, so + we read two more bytes than necessary, and we tack on + another byte for null termination. */ + buffer = kmalloc(len+3, GFP_KERNEL); + if (buffer == NULL) { + parport_release(dev); + parport_close(dev); + return -ENOMEM; + } + memcpy(buffer, length, 2); + *buf_out = buffer; + + retval = parport_read (dev->port, buffer+2, len); + + if (retval == len) + printk (KERN_DEBUG + "%s: device reported incorrect " + "length field (%d, should be two less: %Zd)\n", + dev->port->name, len, retval+2); + else if (retval != len - 2) + printk (KERN_DEBUG "%s: read %Zd bytes, expected %Zd.\n", dev->port->name, retval, len); - /* Some printer manufacturers mistakenly believe that - the length field is supposed to be _exclusive_. - In addition, there are broken devices out there - that don't even finish off with a semi-colon. */ - if (buffer[len - 1] != ';') { - ssize_t diff; - diff = parport_read (dev->port, buffer + len, 2); - retval += diff; - - if (diff) - printk (KERN_DEBUG - "%s: device reported incorrect " - "length field (%d, should be %Zd)\n", - dev->port->name, idlen, retval); - else { - /* One semi-colon short of a device ID. */ - buffer[len++] = ';'; - printk (KERN_DEBUG "%s: faking semi-colon\n", - dev->port->name); - - /* If we get here, I don't think we - need to worry about the possible - standard violation of having read - more than we were told to. The - device is non-compliant anyhow. */ - } - } + if (retval >= 0) + len = retval + 2; - end_id: buffer[len] = '\0'; + if (dev->port->probe_strings[dev->daisy+1]) + kfree(dev->port->probe_strings[dev->daisy+1]); + dev->port->probe_strings[dev->daisy+1] = buffer; + + end_id: parport_negotiate (dev->port, IEEE1284_MODE_COMPAT); } - parport_release (dev); - - if (retval > 2) - parse_data (dev->port, dev->daisy, buffer); + parport_release (dev); parport_close (dev); return retval; +} + +#define for_each_substr(string, string_end, sep, sub, sub_end, code) { \ + const char *sub = string; \ + const char *sub_end = string; \ + for(; sub_end != string_end; sub = sub_end + 1) { \ + sub_end = memchr(sub, sep, string_end - sub); \ + if (sub_end == NULL) sub_end = string_end; \ + while ((*sub == ' ' || *sub == '\t') && sub != sub_end) \ + sub++; \ + { code; } \ + } \ +} + + +/* parport_match_str compares an IEEE-1284.3 device ID string + (including the initial two length bytes) against a null-terminated + ID pattern. + + An IEEE-1284.3 device ID string is a semicolon-separated list + of key:value pairs. For example, it might look like: + + CLS:PRINTER;MDL:DeskJet-600. + + Like the device ID string, the usb_device_id pattern is also a + string in the same format, although it does not include the initial + two length bytes. + + The order in which the semicolon-separated fields occur is irrelevant. + So, for example, a printer exporting "CLS:PRINTER;MDL:DeskJet-600" + will match the pattern "MDL:DeskJet-600;CLS:PRINTER". Additionally, + the value in the key:value pairs can be a comma separated list. So, + for example, a pattern of "CMD:CPIA-1" will match "CMD:foo,CPIA-1". + + parport_match_str skips any white space after the ";" or ":" characters, + to accomodate some devices that add it. + + Currently, parport_match_id does not replace IEEE-1284 keyword + abbreviations. So, device drivers should include strings to match + all possible combinations of abbreviations that they care about. + Here is a list of the abbreviations: + + CLS CLASS + CMD COMMAND SET + DES DESCRIPTION + MDL MODEL + MFG MANUFACTURER + + Also, here is a list of known values that devices use + in their "CLASS" fields: + + PRINTER Printer + MODEM Modem + NET Network device + HDC Hard disk + PCMCIA PCMCIA + MEDIA Multimedia device + FDC Floppy disk + PORTS Ports + SCANNER Scanner + DIGICAM Digital camera + SCSIADAPTER SCSI adapter +*/ + + +static inline int +parport_match_str(const char *probe_str, const char *pattern) +{ + const char *probe_str_end; + int matched; + const char *pattern_end = pattern + strlen(pattern); + + probe_str_end = probe_str + strlen(probe_str); + + for_each_substr(pattern, pattern_end, ';', pat, pat_end, { + char *pat_colon = memchr(pat, ':', pat_end - pat); + int key_len; + int patval_len; + if (pat_colon == NULL) + continue; + key_len = pat_colon - pat + 1; + patval_len = (pat_end - pat_colon) - 1; + matched = 0; + for_each_substr(probe_str, probe_str_end,';', probe,probe_end,{ + if (pat_end - pat > probe_end - probe) + continue; + + /* Compare up the the ':' */ + if (memcmp(probe, pat, key_len)) + continue; + + /* Now find something that matches after ':'*/ + for_each_substr(probe + key_len, probe_end, ',' , + value, value_end, { + if (value_end - value != patval_len) + continue; + if (!memcmp(value, pat_colon + 1, patval_len)){ + matched = 1; + break; + } + }); + if (matched) + break; + }); + if (matched == 0) + break; + }); + return matched; +} + +const struct parport_device_id * +parport_match_id(const char *probe_str, + const struct parport_device_id *ids) { + + if (probe_str == NULL || probe_str[0] == '\0') + return NULL; + + probe_str += 2; /* Skip the length field */ + while(ids->pattern != NULL) { + if (parport_match_str(probe_str, ids->pattern)) + return ids; + ids++; + } + return NULL; } Only in linux/drivers/parport: probe.c~ diff -r -u linux-2.4.0-test13-pre4/drivers/parport/procfs.c linux/drivers/parport/procfs.c --- linux-2.4.0-test13-pre4/drivers/parport/procfs.c Wed Jul 5 11:55:45 2000 +++ linux/drivers/parport/procfs.c Sun Dec 24 01:36:11 2000 @@ -70,10 +70,10 @@ static int do_autoprobe(ctl_table *table, int write, struct file *filp, void *result, size_t *lenp) { - struct parport_device_info *info = table->extra2; - const char *str; - char buffer[256]; - int len = 0; + const int devnum = (int) table->extra2; + const unsigned char *str; + int len; + const static char lf = '\n'; if (write) /* permissions stop this */ return -EACCES; @@ -83,20 +83,10 @@ return 0; } - if ((str = info->class_name) != NULL) - len += sprintf (buffer + len, "CLASS:%s;\n", str); - - if ((str = info->model) != NULL) - len += sprintf (buffer + len, "MODEL:%s;\n", str); - - if ((str = info->mfr) != NULL) - len += sprintf (buffer + len, "MANUFACTURER:%s;\n", str); - - if ((str = info->description) != NULL) - len += sprintf (buffer + len, "DESCRIPTION:%s;\n", str); - - if ((str = info->cmdset) != NULL) - len += sprintf (buffer + len, "COMMAND SET:%s;\n", str); + len = parport_get_id(devnum, &str); + if (len < 0) + return len; + len++; if (len > *lenp) len = *lenp; @@ -105,7 +95,10 @@ filp->f_pos += len; - return copy_to_user (result, buffer, len) ? -EFAULT : 0; + if (copy_to_user (result, str, len-1) != 0) + return -EFAULT; + + return copy_to_user(result+len-1, &lf, 1) ? -EFAULT : 0; } #endif /* IEEE1284.3 support. */ @@ -394,7 +387,7 @@ t->vars[5].child = t->device_dir; for (i = 0; i < 5; i++) - t->vars[6 + i].extra2 = &port->probe_info[i]; + t->vars[6 + i].extra2 = (void*) i; t->port_dir[0].procname = port->name; t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */ diff -r -u linux-2.4.0-test13-pre4/drivers/parport/share.c linux/drivers/parport/share.c --- linux-2.4.0-test13-pre4/drivers/parport/share.c Mon Jul 24 18:59:27 2000 +++ linux/drivers/parport/share.c Sun Dec 24 01:36:11 2000 @@ -277,16 +277,8 @@ { int d; for (d = 0; d < 5; d++) { - if (port->probe_info[d].class_name) - kfree (port->probe_info[d].class_name); - if (port->probe_info[d].mfr) - kfree (port->probe_info[d].mfr); - if (port->probe_info[d].model) - kfree (port->probe_info[d].model); - if (port->probe_info[d].cmdset) - kfree (port->probe_info[d].cmdset); - if (port->probe_info[d].description) - kfree (port->probe_info[d].description); + if (port->probe_strings[d]) + kfree (port->probe_strings[d]); } kfree(port->name); @@ -380,7 +372,6 @@ { struct parport *tmp; int portnum; - int device; char *name; tmp = kmalloc(sizeof(struct parport), GFP_KERNEL); @@ -421,7 +412,6 @@ tmp->ops = ops; tmp->portnum = tmp->number = portnum; tmp->physport = tmp; - memset (tmp->probe_info, 0, 5 * sizeof (struct parport_device_info)); tmp->cad_lock = RW_LOCK_UNLOCKED; spin_lock_init(&tmp->waitlist_lock); spin_lock_init(&tmp->pardevice_lock); @@ -464,10 +454,6 @@ if (!portlist) portlist = tmp; spin_unlock(&parportlist_lock); - - for (device = 0; device < 5; device++) - /* assume the worst */ - tmp->probe_info[device].class = PARPORT_CLASS_LEGACY; tmp->waithead = tmp->waittail = NULL; --- linux-2.4.0-test13-pre4/drivers/char/lp.c Thu Oct 12 14:20:47 2000 +++ linux/drivers/char/lp.c Sun Dec 24 01:36:11 2000 @@ -141,6 +141,13 @@ /* ROUND_UP macro from fs/select.c */ #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) +static struct parport_device_id printer_id_tbl[] = { + { "CLS:PRINTER" }, + { "CLASS:PRINTER" }, + { } +}; +MODULE_DEVICE_TABLE(parport, printer_id_tbl); + static devfs_handle_t devfs_handle = NULL; struct lp_struct lp_table[LP_NO]; @@ -703,7 +710,7 @@ case LP_PARPORT_UNSPEC: case LP_PARPORT_AUTO: if (parport_nr[0] == LP_PARPORT_AUTO && - port->probe_info[0].class != PARPORT_CLASS_PRINTER) + parport_match_id(port->probe_strings[0], printer_id_tbl)) return; if (lp_count == LP_NO) { printk("lp: ignoring parallel port (max. %d)\n",LP_NO); --- linux-2.4.0-test13-pre4/drivers/media/video/c-qcam.c Mon Nov 27 17:47:38 2000 +++ linux/drivers/media/video/c-qcam.c Sun Dec 24 17:13:55 2000 @@ -38,6 +38,16 @@ #include #include +static struct parport_device_id qcam_id_tbl[] = { + { "CLS:MEDIA;MDL:Color QuickCam 2.0" }, + { "CLASS:MEDIA;MDL:Color QuickCam 2.0" }, + { "CLS:MEDIA;MODEL:Color QuickCam 2.0" }, + { "CLASS:MEDIA;MODEL:Color QuickCam 2.0" }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(parport, qcam_id_tbl); + struct qcam_device { struct video_device vdev; struct pardevice *pdev; @@ -192,10 +202,7 @@ /* XXX Currently parport provides no way to distinguish between "the IEEE probe was not done" and "the probe was done, but no device was found". Fix this one day. */ - if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA - && qcam->pport->probe_info[0].model - && !strcmp(qcam->pdev->port->probe_info[0].model, - "Color QuickCam 2.0")) { + if (parport_match_id(qcam->pport->probe_strings[0], qcam_id_tbl)) { printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n"); return 1; } --- linux-2.4.0-test13-pre4/drivers/media/video/cpia_pp.c Mon Mar 27 10:22:31 2000 +++ linux/drivers/media/video/cpia_pp.c Sun Dec 24 17:15:19 2000 @@ -147,6 +147,26 @@ int stream_irq; }; + +/* qcam_ieee1284_id is declared as its own variable so that it + can be in the __initdata section. */ +static struct parport_device_id cpia_id_tbl[] = { + { "CLS:MEDIA;CMD:CPIA_1" }, + { "CLASS:MEDIA;CMD:CPIA_1" } , + { "CLS:MEDIA;COMMAND SET:CPIA_1" }, + { "CLASS:MEDIA;COMMAND_SET:CPIA_1" }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(parport, cpia_id_tbl); + +static struct parport_device_id cpia_reject_tbl[] = { + { "CMD:" }, + { "COMMAND SET:" }, + { } /* Terminating entry */ +}; + + static struct cpia_camera_ops cpia_pp_ops = { cpia_pp_open, @@ -627,9 +647,8 @@ { case PPCPIA_PARPORT_UNSPEC: case PPCPIA_PARPORT_AUTO: - if (port->probe_info[0].class != PARPORT_CLASS_MEDIA || - port->probe_info[0].cmdset == NULL || - strncmp(port->probe_info[0].cmdset, "CPIA_1", 6) != 0) + if (!parport_match_id(port->probe_strings[0], cpia_id_tbl) && + parport_match_id(port->probe_strings[0], cpia_reject_tbl)) return; cpia_pp_register(port);