/* $Id: parport_probe.c,v 1.1 1999/07/03 08:56:17 davem Exp $
 * Parallel port device probing code
 *
 * Authors:    Carsten Gross, carsten@sol.wohnheim.uni-ulm.de
 *             Philip Blundell <Philip.Blundell@pobox.com>
 */

#include <linux/parport.h>
#include <linux/ctype.h>
#include <asm/uaccess.h>

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(KERN_WARNING "%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;
			*(sep++) = 0;
			/* Get rid of trailing blanks */
			u = sep + strlen (sep) - 1;
			while (u >= p && *u == ' ')
				*u-- = '\0';
			u = p;
			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 retval = -ENXIO;
	struct pardevice *dev = parport_open (devnum, "Device ID probe",
					      NULL, NULL, NULL, 0, NULL);
	if (!dev)
		return -ENXIO;

	parport_claim_or_block (dev);

	/* Negotiate to compatibility mode, and then to device ID mode.
	 * (This is in case we are already in device ID mode.) */
	parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
	retval = parport_negotiate (dev->port,
				    IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID);

	if (!retval) {
		int idlen;
		unsigned char length[2];

		/* First two bytes are MSB,LSB of inclusive length. */
		retval = parport_read (dev->port, length, 2);

		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);

		if (retval != len)
			printk (KERN_DEBUG "%s: only read %Zd of %Zd ID bytes\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. */
			}
		}

	end_id:
		buffer[len] = '\0';
		parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
	}
	parport_release (dev);

	if (retval > 2)
		parse_data (dev->port, dev->daisy, buffer);

	parport_close (dev);
	return retval;
}
