hcd.h 14.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
/*
 * Copyright (c) 2001-2002 by David Brownell
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#ifdef __KERNEL__

/* This file contains declarations of usbcore internals that are mostly
 * used or exposed by Host Controller Drivers.
 */

/*
 * USB Packet IDs (PIDs)
 */
#define USB_PID_UNDEF_0			0xf0
#define USB_PID_OUT			0xe1
#define USB_PID_ACK			0xd2
#define USB_PID_DATA0			0xc3
#define USB_PID_PING			0xb4	/* USB 2.0 */
#define USB_PID_SOF			0xa5
#define USB_PID_NYET			0x96	/* USB 2.0 */
#define USB_PID_DATA2			0x87	/* USB 2.0 */
#define USB_PID_SPLIT			0x78	/* USB 2.0 */
#define USB_PID_IN			0x69
#define USB_PID_NAK			0x5a
#define USB_PID_DATA1			0x4b
#define USB_PID_PREAMBLE		0x3c	/* Token mode */
#define USB_PID_ERR			0x3c	/* USB 2.0: handshake mode */
#define USB_PID_SETUP			0x2d
#define USB_PID_STALL			0x1e
#define USB_PID_MDATA			0x0f	/* USB 2.0 */

/*-------------------------------------------------------------------------*/

/*
 * USB Host Controller Driver (usb_hcd) framework
 *
 * Since "struct usb_bus" is so thin, you can't share much code in it.
 * This framework is a layer over that, and should be more sharable.
54 55 56 57 58 59
 *
 * @authorized_default: Specifies if new devices are authorized to
 *                      connect by default or they require explicit
 *                      user space authorization; this bit is settable
 *                      through /sys/class/usb_host/X/authorized_default.
 *                      For the rest is RO, so we don't lock to r/w it.
L
Linus Torvalds 已提交
60 61 62 63
 */

/*-------------------------------------------------------------------------*/

64
struct usb_hcd {
L
Linus Torvalds 已提交
65 66 67 68 69

	/*
	 * housekeeping
	 */
	struct usb_bus		self;		/* hcd is-a bus */
70
	struct kref		kref;		/* reference counter */
L
Linus Torvalds 已提交
71 72 73 74

	const char		*product_desc;	/* product/vendor string */
	char			irq_descr[24];	/* driver + bus # */

75 76
	struct timer_list	rh_timer;	/* drives root-hub polling */
	struct urb		*status_urb;	/* the current status urb */
77 78 79
#ifdef CONFIG_PM
	struct work_struct	wakeup_work;	/* for remote wakeup */
#endif
L
Linus Torvalds 已提交
80 81 82 83 84

	/*
	 * hardware info/state
	 */
	const struct hc_driver	*driver;	/* hw-specific hooks */
85 86 87 88 89 90

	/* Flags that need to be manipulated atomically */
	unsigned long		flags;
#define HCD_FLAG_HW_ACCESSIBLE	0x00000001
#define HCD_FLAG_SAW_IRQ	0x00000002

L
Linus Torvalds 已提交
91 92
	unsigned		rh_registered:1;/* is root hub registered? */

93 94 95 96 97
	/* The next flag is a stopgap, to be removed when all the HCDs
	 * support the new root-hub polling mechanism. */
	unsigned		uses_new_polling:1;
	unsigned		poll_rh:1;	/* poll for rh status? */
	unsigned		poll_pending:1;	/* status has changed? */
98
	unsigned		wireless:1;	/* Wireless USB HCD */
99
	unsigned		authorized_default:1;
100

L
Linus Torvalds 已提交
101 102 103 104
	int			irq;		/* irq allocated */
	void __iomem		*regs;		/* device memory/io */
	u64			rsrc_start;	/* memory/io resource start */
	u64			rsrc_len;	/* memory/io resource length */
105
	unsigned		power_budget;	/* in mA, 0 = no limit */
L
Linus Torvalds 已提交
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

#define HCD_BUFFER_POOLS	4
	struct dma_pool		*pool [HCD_BUFFER_POOLS];

	int			state;
#	define	__ACTIVE		0x01
#	define	__SUSPEND		0x04
#	define	__TRANSIENT		0x80

#	define	HC_STATE_HALT		0
#	define	HC_STATE_RUNNING	(__ACTIVE)
#	define	HC_STATE_QUIESCING	(__SUSPEND|__TRANSIENT|__ACTIVE)
#	define	HC_STATE_RESUMING	(__SUSPEND|__TRANSIENT)
#	define	HC_STATE_SUSPENDED	(__SUSPEND)

#define	HC_IS_RUNNING(state) ((state) & __ACTIVE)
#define	HC_IS_SUSPENDED(state) ((state) & __SUSPEND)

	/* more shared queuing code would be good; it should support
	 * smarter scheduling, handle transaction translators, etc;
	 * input size of periodic table to an interrupt scheduler. 
	 * (ohci 32, uhci 1024, ehci 256/512/1024).
	 */

	/* The HC driver's private data is stored at the end of
	 * this structure.
	 */
	unsigned long hcd_priv[0]
			__attribute__ ((aligned (sizeof(unsigned long))));
};

/* 2.4 does this a bit differently ... */
static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
{
	return &hcd->self;
}

143 144 145 146
static inline struct usb_hcd *bus_to_hcd (struct usb_bus *bus)
{
	return container_of(bus, struct usb_hcd, self);
}
L
Linus Torvalds 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

struct hcd_timeout {	/* timeouts we allocate */
	struct list_head	timeout_list;
	struct timer_list	timer;
};

/*-------------------------------------------------------------------------*/


struct hc_driver {
	const char	*description;	/* "ehci-hcd" etc */
	const char	*product_desc;	/* product/vendor string */
	size_t		hcd_priv_size;	/* size of private data */

	/* irq handler */
162
	irqreturn_t	(*irq) (struct usb_hcd *hcd);
L
Linus Torvalds 已提交
163 164 165 166 167 168 169 170 171 172 173

	int	flags;
#define	HCD_MEMORY	0x0001		/* HC regs use memory (else I/O) */
#define	HCD_USB11	0x0010		/* USB 1.1 */
#define	HCD_USB2	0x0020		/* USB 2.0 */

	/* called to init HCD and root hub */
	int	(*reset) (struct usb_hcd *hcd);
	int	(*start) (struct usb_hcd *hcd);

	/* NOTE:  these suspend/resume calls relate to the HC as
174
	 * a whole, not just the root hub; they're for PCI bus glue.
L
Linus Torvalds 已提交
175
	 */
176
	/* called after suspending the hub, before entering D3 etc */
177
	int	(*suspend) (struct usb_hcd *hcd, pm_message_t message);
L
Linus Torvalds 已提交
178

179
	/* called after entering D0 (etc), before resuming the hub */
L
Linus Torvalds 已提交
180 181 182 183 184
	int	(*resume) (struct usb_hcd *hcd);

	/* cleanly make HCD stop writing memory and doing I/O */
	void	(*stop) (struct usb_hcd *hcd);

185 186 187
	/* shutdown HCD */
	void	(*shutdown) (struct usb_hcd *hcd);

L
Linus Torvalds 已提交
188 189 190 191
	/* return current frame number */
	int	(*get_frame_number) (struct usb_hcd *hcd);

	/* manage i/o requests, device state */
192 193 194 195
	int	(*urb_enqueue)(struct usb_hcd *hcd,
				struct urb *urb, gfp_t mem_flags);
	int	(*urb_dequeue)(struct usb_hcd *hcd,
				struct urb *urb, int status);
L
Linus Torvalds 已提交
196 197 198 199 200 201 202 203 204 205

	/* hw synch, freeing endpoint resources that urb_dequeue can't */
	void 	(*endpoint_disable)(struct usb_hcd *hcd,
			struct usb_host_endpoint *ep);

	/* root hub support */
	int		(*hub_status_data) (struct usb_hcd *hcd, char *buf);
	int		(*hub_control) (struct usb_hcd *hcd,
				u16 typeReq, u16 wValue, u16 wIndex,
				char *buf, u16 wLength);
206 207
	int		(*bus_suspend)(struct usb_hcd *);
	int		(*bus_resume)(struct usb_hcd *);
L
Linus Torvalds 已提交
208
	int		(*start_port_reset)(struct usb_hcd *, unsigned port_num);
209 210
	void		(*hub_irq_enable)(struct usb_hcd *);
		/* Needed only if port-change IRQs are level-triggered */
L
Linus Torvalds 已提交
211 212
};

213 214 215 216 217
extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
		int status);
extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb);

A
Alan Stern 已提交
218 219
extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags);
extern int usb_hcd_unlink_urb (struct urb *urb, int status);
220
extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb);
A
Alan Stern 已提交
221 222 223
extern void usb_hcd_endpoint_disable (struct usb_device *udev,
		struct usb_host_endpoint *ep);
extern int usb_hcd_get_frame_number (struct usb_device *udev);
L
Linus Torvalds 已提交
224 225 226

extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
		struct device *dev, char *bus_name);
227
extern struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd);
L
Linus Torvalds 已提交
228 229 230 231 232
extern void usb_put_hcd (struct usb_hcd *hcd);
extern int usb_add_hcd(struct usb_hcd *hcd,
		unsigned int irqnum, unsigned long irqflags);
extern void usb_remove_hcd(struct usb_hcd *hcd);

233 234 235
struct platform_device;
extern void usb_hcd_platform_shutdown(struct platform_device* dev);

L
Linus Torvalds 已提交
236 237 238 239 240 241 242 243
#ifdef CONFIG_PCI
struct pci_dev;
struct pci_device_id;
extern int usb_hcd_pci_probe (struct pci_dev *dev,
				const struct pci_device_id *id);
extern void usb_hcd_pci_remove (struct pci_dev *dev);

#ifdef CONFIG_PM
244
extern int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t state);
L
Linus Torvalds 已提交
245 246 247
extern int usb_hcd_pci_resume (struct pci_dev *dev);
#endif /* CONFIG_PM */

248 249
extern void usb_hcd_pci_shutdown (struct pci_dev *dev);

L
Linus Torvalds 已提交
250 251 252 253 254 255 256
#endif /* CONFIG_PCI */

/* pci-ish (pdev null is ok) buffer alloc/mapping support */
int hcd_buffer_create (struct usb_hcd *hcd);
void hcd_buffer_destroy (struct usb_hcd *hcd);

void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
A
Al Viro 已提交
257
	gfp_t mem_flags, dma_addr_t *dma);
L
Linus Torvalds 已提交
258 259 260 261
void hcd_buffer_free (struct usb_bus *bus, size_t size,
	void *addr, dma_addr_t dma);

/* generic bus glue, needed for host controllers that don't use PCI */
262
extern irqreturn_t usb_hcd_irq (int irq, void *__hcd);
263

L
Linus Torvalds 已提交
264
extern void usb_hc_died (struct usb_hcd *hcd);
265
extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
L
Linus Torvalds 已提交
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337

/* -------------------------------------------------------------------------- */

/* Enumeration is only for the hub driver, or HCD virtual root hubs */
extern struct usb_device *usb_alloc_dev(struct usb_device *parent,
					struct usb_bus *, unsigned port);
extern int usb_new_device(struct usb_device *dev);
extern void usb_disconnect(struct usb_device **);

extern int usb_get_configuration(struct usb_device *dev);
extern void usb_destroy_configuration(struct usb_device *dev);

/*-------------------------------------------------------------------------*/

/*
 * HCD Root Hub support
 */

#include "hub.h"

/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
#define DeviceRequest \
	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
#define DeviceOutRequest \
	((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)

#define InterfaceRequest \
	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)

#define EndpointRequest \
	((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define EndpointOutRequest \
	((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)

/* class requests from the USB 2.0 hub spec, table 11-15 */
/* GetBusState and SetHubDescriptor are optional, omitted */
#define ClearHubFeature		(0x2000 | USB_REQ_CLEAR_FEATURE)
#define ClearPortFeature	(0x2300 | USB_REQ_CLEAR_FEATURE)
#define GetHubDescriptor	(0xa000 | USB_REQ_GET_DESCRIPTOR)
#define GetHubStatus		(0xa000 | USB_REQ_GET_STATUS)
#define GetPortStatus		(0xa300 | USB_REQ_GET_STATUS)
#define SetHubFeature		(0x2000 | USB_REQ_SET_FEATURE)
#define SetPortFeature		(0x2300 | USB_REQ_SET_FEATURE)


/*-------------------------------------------------------------------------*/

/*
 * Generic bandwidth allocation constants/support
 */
#define FRAME_TIME_USECS	1000L
#define BitTime(bytecount)  (7 * 8 * bytecount / 6)  /* with integer truncation */
		/* Trying not to use worst-case bit-stuffing
                   of (7/6 * 8 * bytecount) = 9.33 * bytecount */
		/* bytecount = data payload byte count */

#define NS_TO_US(ns)	((ns + 500L) / 1000L)
			/* convert & round nanoseconds to microseconds */


/*
 * Full/low speed bandwidth allocation constants/support.
 */
#define BW_HOST_DELAY	1000L		/* nanoseconds */
#define BW_HUB_LS_SETUP	333L		/* nanoseconds */
                        /* 4 full-speed bit times (est.) */

#define FRAME_TIME_BITS         12000L		/* frame = 1 millisecond */
#define FRAME_TIME_MAX_BITS_ALLOC	(90L * FRAME_TIME_BITS / 100L)
#define FRAME_TIME_MAX_USECS_ALLOC	(90L * FRAME_TIME_USECS / 100L)

/*
338
 * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed
L
Linus Torvalds 已提交
339 340 341 342
 * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
 * to preallocate bandwidth)
 */
#define USB2_HOST_DELAY	5	/* nsec, guess */
343 344
#define HS_NSECS(bytes) ( ((55 * 8 * 2083) \
	+ (2083UL * (3 + BitTime(bytes))))/1000 \
L
Linus Torvalds 已提交
345
	+ USB2_HOST_DELAY)
346 347
#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083) \
	+ (2083UL * (3 + BitTime(bytes))))/1000 \
L
Linus Torvalds 已提交
348
	+ USB2_HOST_DELAY)
349 350
#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes))
L
Linus Torvalds 已提交
351 352 353 354 355 356 357 358 359 360 361 362 363 364

extern long usb_calc_bus_time (int speed, int is_input,
			int isoc, int bytecount);

/*-------------------------------------------------------------------------*/

extern void usb_set_device_state(struct usb_device *udev,
		enum usb_device_state new_state);

/*-------------------------------------------------------------------------*/

/* exported only within usbcore */

extern struct list_head usb_bus_list;
365
extern struct mutex usb_bus_list_lock;
L
Linus Torvalds 已提交
366 367
extern wait_queue_head_t usb_kill_urb_queue;

368 369
extern void usb_enable_root_hub_irq (struct usb_bus *bus);

L
Linus Torvalds 已提交
370 371 372 373 374
extern int usb_find_interface_driver (struct usb_device *dev,
	struct usb_interface *interface);

#define usb_endpoint_out(ep_dir)	(!((ep_dir) & USB_DIR_IN))

375
#ifdef CONFIG_PM
376
extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
377
extern void usb_root_hub_lost_power (struct usb_device *rhdev);
378 379
extern int hcd_bus_suspend(struct usb_device *rhdev);
extern int hcd_bus_resume(struct usb_device *rhdev);
380
#else
381 382 383 384
static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd)
{
	return;
}
385 386
#endif /* CONFIG_PM */

L
Linus Torvalds 已提交
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
/*
 * USB device fs stuff
 */

#ifdef CONFIG_USB_DEVICEFS

/*
 * these are expected to be called from the USB core/hub thread
 * with the kernel lock held
 */
extern void usbfs_update_special (void);
extern int usbfs_init(void);
extern void usbfs_cleanup(void);

#else /* CONFIG_USB_DEVICEFS */

static inline void usbfs_update_special (void) {}
static inline int usbfs_init(void) { return 0; }
static inline void usbfs_cleanup(void) { }

#endif /* CONFIG_USB_DEVICEFS */

/*-------------------------------------------------------------------------*/

411
#if defined(CONFIG_USB_MON)
L
Linus Torvalds 已提交
412 413 414 415

struct usb_mon_operations {
	void (*urb_submit)(struct usb_bus *bus, struct urb *urb);
	void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err);
416
	void (*urb_complete)(struct usb_bus *bus, struct urb *urb, int status);
L
Linus Torvalds 已提交
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
	/* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
};

extern struct usb_mon_operations *mon_ops;

static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb)
{
	if (bus->monitored)
		(*mon_ops->urb_submit)(bus, urb);
}

static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
    int error)
{
	if (bus->monitored)
		(*mon_ops->urb_submit_error)(bus, urb, error);
}

435 436
static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
		int status)
L
Linus Torvalds 已提交
437 438
{
	if (bus->monitored)
439
		(*mon_ops->urb_complete)(bus, urb, status);
L
Linus Torvalds 已提交
440 441 442 443 444 445 446 447 448 449
}

int usb_mon_register(struct usb_mon_operations *ops);
void usb_mon_deregister(void);

#else

static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {}
static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
    int error) {}
450 451
static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
		int status) {}
L
Linus Torvalds 已提交
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471

#endif /* CONFIG_USB_MON */

/*-------------------------------------------------------------------------*/

/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
// bleech -- resurfaced in 2.4.11 or 2.4.12
#define bitmap 	DeviceRemovable


/*-------------------------------------------------------------------------*/

/* random stuff */

#define	RUN_CONTEXT (in_irq () ? "in_irq" \
		: (in_interrupt () ? "in_interrupt" : "can sleep"))


#endif /* __KERNEL__ */