config.c 13.6 KB
Newer Older
1 2 3 4 5 6
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/byteorder.h>

7 8 9 10 11 12 13 14 15

#define USB_MAXALTSETTING		128	/* Hard limit */
#define USB_MAXENDPOINTS		30	/* Hard limit */

/* these maximums are arbitrary */
#define USB_MAXCONFIG			8
#define USB_MAXINTERFACES		32

static int usb_parse_endpoint(struct usb_host_endpoint *endpoint, unsigned char *buffer, int size)
16
{
17
	unsigned char *buffer0 = buffer;
18 19
	struct usb_descriptor_header *header;
	unsigned char *begin;
20
	int len, numskipped;
21 22 23

	header = (struct usb_descriptor_header *)buffer;
	if (header->bDescriptorType != USB_DT_ENDPOINT) {
24 25
		warn("unexpected descriptor 0x%X, expecting endpoint, 0x%X",
			header->bDescriptorType, USB_DT_ENDPOINT);
26
		return -EINVAL;
27 28
	}

29
	if (header->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE)
30
		memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
31
	else if (header->bLength >= USB_DT_ENDPOINT_SIZE)
32
		memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_SIZE);
33 34 35 36 37 38 39 40 41 42
	else {
		warn("invalid endpoint descriptor");
		return -EINVAL;
	}

	if ((endpoint->desc.bEndpointAddress & ~USB_ENDPOINT_DIR_MASK) >= 16) {
		warn("invalid endpoint address 0x%X",
		    endpoint->desc.bEndpointAddress);
		return -EINVAL;
	}
43

44
	le16_to_cpus(&endpoint->desc.wMaxPacketSize);
45 46 47 48

	buffer += header->bLength;
	size -= header->bLength;

49
	/* Skip over any Class Specific or Vendor Specific descriptors */
50 51 52 53 54 55 56
	begin = buffer;
	numskipped = 0;
	while (size >= sizeof(struct usb_descriptor_header)) {
		header = (struct usb_descriptor_header *)buffer;

		/* If we find another "proper" descriptor then we're done  */
		if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
57
		    (header->bDescriptorType == USB_DT_INTERFACE))
58 59
			break;

60
		dbg("skipping descriptor 0x%X", header->bDescriptorType);
61 62 63 64 65
		numskipped++;

		buffer += header->bLength;
		size -= header->bLength;
	}
66
	if (numskipped) {
67 68
		dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);

69 70 71
		/* Copy any unknown descriptors into a storage area for drivers */
		/*  to later parse */
		len = buffer - begin;
72

73 74 75 76 77
		endpoint->extra = kmalloc(len, GFP_KERNEL);
		if (!endpoint->extra) {
			err("couldn't allocate memory for endpoint extra descriptors");
			return -ENOMEM;
		}
78

79 80
		memcpy(endpoint->extra, begin, len);
		endpoint->extralen = len;
81 82
	}

83
	return buffer - buffer0;
84 85
}

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
static void usb_release_intf(struct device *dev)
{
	struct usb_interface *intf;
	int j;
	int k;

	intf = to_usb_interface(dev);

	if (intf->altsetting) {
		for (j = 0; j < intf->num_altsetting; j++) {
			struct usb_host_interface *as = &intf->altsetting[j];
			if (as->extra)
				kfree(as->extra);

			if (as->endpoint) {
				for (k = 0; k < as->desc.bNumEndpoints; k++)
					if (as->endpoint[k].extra)
						kfree(as->endpoint[k].extra);
				kfree(as->endpoint);
			}
		}
		kfree(intf->altsetting);
	}
	kfree(intf);
}

112
static int usb_parse_interface(struct usb_host_config *config, unsigned char *buffer, int size)
113
{
114
	unsigned char *buffer0 = buffer;
115 116 117
	struct usb_interface_descriptor	*d;
	int inum, asnum;
	struct usb_interface *interface;
118
	struct usb_host_interface *ifp;
119 120
	int len, numskipped;
	struct usb_descriptor_header *header;
121
	unsigned char *begin;
122
	int i, retval;
123

124 125 126 127 128 129
	d = (struct usb_interface_descriptor *) buffer;
	if (d->bDescriptorType != USB_DT_INTERFACE) {
		warn("unexpected descriptor 0x%X, expecting interface, 0x%X",
			d->bDescriptorType, USB_DT_INTERFACE);
		return -EINVAL;
	}
130

131 132
	inum = d->bInterfaceNumber;
	if (inum >= config->desc.bNumInterfaces) {
133

134 135 136 137 138
		/* Skip to the next interface descriptor */
		buffer += d->bLength;
		size -= d->bLength;
		while (size >= sizeof(struct usb_descriptor_header)) {
			header = (struct usb_descriptor_header *) buffer;
139

140 141 142 143
			if (header->bDescriptorType == USB_DT_INTERFACE)
				break;
			buffer += header->bLength;
			size -= header->bLength;
144
		}
145 146
		return buffer - buffer0;
	}
147

148 149 150 151 152 153 154
	interface = config->interface[inum];
	asnum = d->bAlternateSetting;
	if (asnum >= interface->num_altsetting) {
		warn("invalid alternate setting %d for interface %d",
		    asnum, inum);
		return -EINVAL;
	}
155

156
	ifp = &interface->altsetting[asnum];
157 158 159 160 161
	if (ifp->desc.bLength) {
		warn("duplicate descriptor for interface %d altsetting %d",
		    inum, asnum);
		return -EINVAL;
	}
162
	memcpy(&ifp->desc, buffer, USB_DT_INTERFACE_SIZE);
163

164 165
	buffer += d->bLength;
	size -= d->bLength;
166

167 168 169 170 171
	/* Skip over any Class Specific or Vendor Specific descriptors */
	begin = buffer;
	numskipped = 0;
	while (size >= sizeof(struct usb_descriptor_header)) {
		header = (struct usb_descriptor_header *)buffer;
172

173 174 175 176
		/* If we find another "proper" descriptor then we're done  */
		if ((header->bDescriptorType == USB_DT_INTERFACE) ||
		    (header->bDescriptorType == USB_DT_ENDPOINT))
			break;
177

178 179
		dbg("skipping descriptor 0x%X", header->bDescriptorType);
		numskipped++;
180

181 182 183 184 185
		buffer += header->bLength;
		size -= header->bLength;
	}
	if (numskipped) {
		dbg("skipped %d class/vendor specific interface descriptors", numskipped);
186

187 188 189 190
		/* Copy any unknown descriptors into a storage area for */
		/*  drivers to later parse */
		len = buffer - begin;
		ifp->extra = kmalloc(len, GFP_KERNEL);
191

192 193
		if (!ifp->extra) {
			err("couldn't allocate memory for interface extra descriptors");
194
			return -ENOMEM;
195
		}
196 197 198
		memcpy(ifp->extra, begin, len);
		ifp->extralen = len;
	}
199

200
	if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) {
201 202
		warn("too many endpoints for interface %d altsetting %d",
		    inum, asnum);
203 204
		return -EINVAL;
	}
205

206 207 208 209 210 211 212
	len = ifp->desc.bNumEndpoints * sizeof(struct usb_host_endpoint);
	ifp->endpoint = kmalloc(len, GFP_KERNEL);
	if (!ifp->endpoint) {
		err("out of memory");
		return -ENOMEM;
	}
	memset(ifp->endpoint, 0, len);
213

214 215
	for (i = 0; i < ifp->desc.bNumEndpoints; i++) {
		if (size < USB_DT_ENDPOINT_SIZE) {
216
			warn("ran out of descriptors while parsing endpoints");
217
			return -EINVAL;
218 219
		}

220 221 222
		retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
		if (retval < 0)
			return retval;
223

224 225
		buffer += retval;
		size -= retval;
226 227
	}

228
	return buffer - buffer0;
229 230
}

231
int usb_parse_configuration(struct usb_host_config *config, char *buffer, int size)
232
{
233
	int nintf, nintf_orig;
234
	int i, j;
235
	struct usb_interface *interface;
236 237 238
	char *buffer2;
	int size2;
	struct usb_descriptor_header *header;
239 240 241
	int numskipped, len;
	char *begin;
	int retval;
242

243
	memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
244 245 246 247 248 249
	if (config->desc.bDescriptorType != USB_DT_CONFIG ||
	    config->desc.bLength < USB_DT_CONFIG_SIZE) {
		warn("invalid configuration descriptor");
		return -EINVAL;
	}
	config->desc.wTotalLength = size;
250

251
	nintf = nintf_orig = config->desc.bNumInterfaces;
252 253 254 255
	if (nintf > USB_MAXINTERFACES) {
		warn("too many interfaces (%d max %d)",
		    nintf, USB_MAXINTERFACES);
		config->desc.bNumInterfaces = nintf = USB_MAXINTERFACES;
256 257
	}

258
	for (i = 0; i < nintf; ++i) {
259 260 261 262
		interface = config->interface[i] =
		    kmalloc(sizeof(struct usb_interface), GFP_KERNEL);
		dbg("kmalloc IF %p, numif %i", interface, i);
		if (!interface) {
263
			err("out of memory");
264
			return -ENOMEM;
265
		}
266 267 268 269 270 271
		memset(interface, 0, sizeof(struct usb_interface));
		interface->dev.release = usb_release_intf;
		device_initialize(&interface->dev);

		/* put happens in usb_destroy_configuration */
		get_device(&interface->dev);
272 273
	}

274 275
	/* Go through the descriptors, checking their length and counting the
	 * number of altsettings for each interface */
276 277 278 279 280 281
	buffer2 = buffer;
	size2 = size;
	j = 0;
	while (size2 >= sizeof(struct usb_descriptor_header)) {
		header = (struct usb_descriptor_header *) buffer2;
		if ((header->bLength > size2) || (header->bLength < 2)) {
282
			warn("invalid descriptor of length %d", header->bLength);
283 284 285 286
			return -EINVAL;
		}

		if (header->bDescriptorType == USB_DT_INTERFACE) {
287 288
			struct usb_interface_descriptor *d;

289 290 291 292
			if (header->bLength < USB_DT_INTERFACE_SIZE) {
				warn("invalid interface descriptor");
				return -EINVAL;
			}
293 294 295 296 297 298 299 300 301
			d = (struct usb_interface_descriptor *) header;
			i = d->bInterfaceNumber;
			if (i >= nintf_orig) {
				warn("invalid interface number (%d/%d)",
				    i, nintf_orig);
				return -EINVAL;
			}
			if (i < nintf)
				++config->interface[i]->num_altsetting;
302 303 304 305 306 307 308 309 310 311 312 313

		} else if ((header->bDescriptorType == USB_DT_DEVICE ||
		    header->bDescriptorType == USB_DT_CONFIG) && j) {
			warn("unexpected descriptor type 0x%X", header->bDescriptorType);
			return -EINVAL;
		}

		j = 1;
		buffer2 += header->bLength;
		size2 -= header->bLength;
	}

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
	/* Allocate the altsetting arrays */
	for (i = 0; i < config->desc.bNumInterfaces; ++i) {
		interface = config->interface[i];
		if (interface->num_altsetting > USB_MAXALTSETTING) {
			warn("too many alternate settings for interface %d (%d max %d)\n",
			    i, interface->num_altsetting, USB_MAXALTSETTING);
			return -EINVAL;
		}
		if (interface->num_altsetting == 0) {
			warn("no alternate settings for interface %d", i);
			return -EINVAL;
		}

		len = sizeof(*interface->altsetting) * interface->num_altsetting;
		interface->altsetting = kmalloc(len, GFP_KERNEL);
		if (!interface->altsetting) {
			err("couldn't kmalloc interface->altsetting");
			return -ENOMEM;
		}
		memset(interface->altsetting, 0, len);
	}

336 337
	buffer += config->desc.bLength;
	size -= config->desc.bLength;
338

339 340 341 342 343
	/* Skip over any Class Specific or Vendor Specific descriptors */
	begin = buffer;
	numskipped = 0;
	while (size >= sizeof(struct usb_descriptor_header)) {
		header = (struct usb_descriptor_header *)buffer;
344

345 346
		/* If we find another "proper" descriptor then we're done  */
		if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
347
		    (header->bDescriptorType == USB_DT_INTERFACE))
348
			break;
349

350 351
		dbg("skipping descriptor 0x%X", header->bDescriptorType);
		numskipped++;
352

353 354 355 356 357
		buffer += header->bLength;
		size -= header->bLength;
	}
	if (numskipped) {
		dbg("skipped %d class/vendor specific configuration descriptors", numskipped);
358

359 360 361 362 363 364 365
		/* Copy any unknown descriptors into a storage area for */
		/*  drivers to later parse */
		len = buffer - begin;
		config->extra = kmalloc(len, GFP_KERNEL);
		if (!config->extra) {
			err("couldn't allocate memory for config extra descriptors");
			return -ENOMEM;
366 367
		}

368 369 370
		memcpy(config->extra, begin, len);
		config->extralen = len;
	}
371

372
	/* Parse all the interface/altsetting descriptors */
373 374
	while (size >= sizeof(struct usb_descriptor_header)) {
		retval = usb_parse_interface(config, buffer, size);
375 376 377 378 379 380 381
		if (retval < 0)
			return retval;

		buffer += retval;
		size -= retval;
	}

382 383 384 385 386 387 388 389 390 391 392
	/* Check for missing altsettings */
	for (i = 0; i < nintf; ++i) {
		interface = config->interface[i];
		for (j = 0; j < interface->num_altsetting; ++j) {
			if (!interface->altsetting[j].desc.bLength) {
				warn("missing altsetting %d for interface %d", j, i);
				return -EINVAL;
			}
		}
	}

393 394 395 396 397 398 399
	return size;
}

// hub-only!! ... and only exported for reset/reinit path.
// otherwise used internally on disconnect/destroy path
void usb_destroy_configuration(struct usb_device *dev)
{
400
	int c, i;
401

402 403 404 405 406 407 408 409 410 411 412
	if (!dev->config)
		return;

	if (dev->rawdescriptors) {
		for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
			kfree(dev->rawdescriptors[i]);

		kfree(dev->rawdescriptors);
	}

	for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
413
		struct usb_host_config *cf = &dev->config[c];
414

415
		for (i = 0; i < cf->desc.bNumInterfaces; i++) {
416
			struct usb_interface *ifp = cf->interface[i];
417 418 419

			if (ifp)
				put_device(&ifp->dev);
420
		}
421
		kfree(cf->extra);
422 423 424 425 426 427 428 429 430
	}
	kfree(dev->config);
}


// hub-only!! ... and only in reset path, or usb_new_device()
// (used by real hubs and virtual root hubs)
int usb_get_configuration(struct usb_device *dev)
{
431
	int ncfg = dev->descriptor.bNumConfigurations;
432 433 434 435 436 437
	int result;
	unsigned int cfgno, length;
	unsigned char *buffer;
	unsigned char *bigbuffer;
 	struct usb_config_descriptor *desc;

438 439 440 441
	if (ncfg > USB_MAXCONFIG) {
		warn("too many configurations (%d max %d)",
		    ncfg, USB_MAXCONFIG);
		dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
442 443
	}

444 445
	if (ncfg < 1) {
		warn("no configurations");
446 447 448
		return -EINVAL;
	}

449 450
	length = ncfg * sizeof(struct usb_host_config);
	dev->config = kmalloc(length, GFP_KERNEL);
451 452
	if (!dev->config) {
		err("out of memory");
453
		return -ENOMEM;
454
	}
455
	memset(dev->config, 0, length);
456

457 458
	length = ncfg * sizeof(char *);
	dev->rawdescriptors = kmalloc(length, GFP_KERNEL);
459 460 461 462
	if (!dev->rawdescriptors) {
		err("out of memory");
		return -ENOMEM;
	}
463
	memset(dev->rawdescriptors, 0, length);
464 465 466 467 468 469 470 471

	buffer = kmalloc(8, GFP_KERNEL);
	if (!buffer) {
		err("unable to allocate memory for configuration descriptors");
		return -ENOMEM;
	}
	desc = (struct usb_config_descriptor *)buffer;

472
	for (cfgno = 0; cfgno < ncfg; cfgno++) {
473 474 475 476 477 478 479
		/* We grab the first 8 bytes so we know how long the whole */
		/*  configuration is */
		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
		if (result < 8) {
			if (result < 0)
				err("unable to get descriptor");
			else {
480
				warn("config descriptor too short (expected %i, got %i)", 8, result);
481 482 483 484 485 486
				result = -EINVAL;
			}
			goto err;
		}

  	  	/* Get the full buffer */
487
		length = max((int) le16_to_cpu(desc->wTotalLength), USB_DT_CONFIG_SIZE);
488 489 490 491 492 493 494 495 496 497 498 499 500 501

		bigbuffer = kmalloc(length, GFP_KERNEL);
		if (!bigbuffer) {
			err("unable to allocate memory for configuration descriptors");
			result = -ENOMEM;
			goto err;
		}

		/* Now that we know the length, get the whole thing */
		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);
		if (result < 0) {
			err("couldn't get all of config descriptors");
			kfree(bigbuffer);
			goto err;
502 503
		}

504 505 506 507 508 509 510 511 512
		if (result < length) {
			err("config descriptor too short (expected %i, got %i)", length, result);
			result = -EINVAL;
			kfree(bigbuffer);
			goto err;
		}

		dev->rawdescriptors[cfgno] = bigbuffer;

513
		result = usb_parse_configuration(&dev->config[cfgno], bigbuffer, length);
514 515 516
		if (result > 0)
			dbg("descriptor data left");
		else if (result < 0) {
517
			++cfgno;
518 519 520 521 522 523 524 525 526 527 528 529
			goto err;
		}
	}

	kfree(buffer);
	return 0;
err:
	kfree(buffer);
	dev->descriptor.bNumConfigurations = cfgno;
	return result;
}