Exemplo n.º 1
0
/**
 * qla2x00_prep_cont_type0_iocb() - Initialize a Continuation Type 0 IOCB.
 * @ha: HA context
 *
 * Returns a pointer to the Continuation Type 0 IOCB packet.
 */
static inline cont_entry_t *
qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *ha)
{
	cont_entry_t *cont_pkt;

	/* Adjust ring index. */
	ha->req_ring_index++;
	if (ha->req_ring_index == ha->request_q_length) {
		ha->req_ring_index = 0;
		ha->request_ring_ptr = ha->request_ring;
	} else {
		ha->request_ring_ptr++;
	}

	cont_pkt = (cont_entry_t *)ha->request_ring_ptr;

	/* Load packet defaults. */
	*((uint32_t *)(&cont_pkt->entry_type)) =
	    __constant_cpu_to_le32(CONTINUE_TYPE);

	return (cont_pkt);
}
Exemplo n.º 2
0
/**
 * qla2x00_prep_cont_type1_iocb() - Initialize a Continuation Type 1 IOCB.
 * @ha: HA context
 *
 * Returns a pointer to the continuation type 1 IOCB packet.
 */
static inline cont_a64_entry_t *
qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha)
{
	cont_a64_entry_t *cont_pkt;

	struct req_que *req = vha->req;
	/* Adjust ring index. */
	req->ring_index++;
	if (req->ring_index == req->length) {
		req->ring_index = 0;
		req->ring_ptr = req->ring;
	} else {
		req->ring_ptr++;
	}

	cont_pkt = (cont_a64_entry_t *)req->ring_ptr;

	/* Load packet defaults. */
	*((uint32_t *)(&cont_pkt->entry_type)) =
	    __constant_cpu_to_le32(CONTINUE_A64_TYPE);

	return (cont_pkt);
}
Exemplo n.º 3
0
/**
 * gserial_setup - initialize TTY driver for one or more ports
 * @g: gadget to associate with these ports
 * @count: how many ports to support
 * Context: may sleep
 *
 * The TTY stack needs to know in advance how many devices it should
 * plan to manage.  Use this call to set up the ports you will be
 * exporting through USB.  Later, connect them to functions based
 * on what configuration is activated by the USB host; and disconnect
 * them as appropriate.
 *
 * An example would be a two-configuration device in which both
 * configurations expose port 0, but through different functions.
 * One configuration could even expose port 1 while the other
 * one doesn't.
 *
 * Returns negative errno or zero.
 */
int __init gserial_setup(struct usb_gadget *g, unsigned count)
{
	unsigned			i;
	struct usb_cdc_line_coding	coding;
	int				status;

	if (count == 0 || count > N_PORTS)
		return -EINVAL;

	gs_tty_driver = alloc_tty_driver(count);
	if (!gs_tty_driver)
		return -ENOMEM;

	gs_tty_driver->owner = THIS_MODULE;
	gs_tty_driver->driver_name = "g_serial";
	gs_tty_driver->name = PREFIX;
	gs_tty_driver->major = 127;
	/* uses dynamically assigned dev_t values */

	gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
	gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
	gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
	gs_tty_driver->init_termios = tty_std_termios;

	/* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
	 * MS-Windows.  Otherwise, most of these flags shouldn't affect
	 * anything unless we were to actually hook up to a serial line.
	 */
	gs_tty_driver->init_termios.c_cflag =
			B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	gs_tty_driver->init_termios.c_ispeed = 9600;
	gs_tty_driver->init_termios.c_ospeed = 9600;

	coding.dwDTERate = __constant_cpu_to_le32(9600);
	coding.bCharFormat = 8;
	coding.bParityType = USB_CDC_NO_PARITY;
	coding.bDataBits = USB_CDC_1_STOP_BITS;

	tty_set_operations(gs_tty_driver, &gs_tty_ops);

	/* make devices be openable */
	for (i = 0; i < count; i++) {
		mutex_init(&ports[i].lock);
		status = gs_port_alloc(i, &coding);
		if (status) {
			count = i;
			goto fail;
		}
	}
	n_ports = count;

	/* export the driver ... */
	status = tty_register_driver(gs_tty_driver);
	if (status) {
		put_tty_driver(gs_tty_driver);
		pr_err("%s: cannot register, err %d\n",
				__func__, status);
		goto fail;
	}

	/* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */
	for (i = 0; i < count; i++) {
		struct device	*tty_dev;

		tty_dev = tty_register_device(gs_tty_driver, i, &g->dev);
		if (IS_ERR(tty_dev))
			pr_warning("%s: no classdev for port %d, err %ld\n",
				__func__, i, PTR_ERR(tty_dev));
	}

	pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
			count, (count == 1) ? "" : "s");

	return status;
fail:
	while (count--)
		kfree(ports[count].port);
	put_tty_driver(gs_tty_driver);
	gs_tty_driver = NULL;
	return status;
}
Exemplo n.º 4
0
	.bDescriptorSubType =	USB_CDC_HEADER_TYPE,
	.bcdCDC =		__constant_cpu_to_le16(0x0110),
};

struct usb_cdc_union_desc		eth_union_desc = {
	.bLength =		sizeof(struct usb_cdc_union_desc),
	.bDescriptorType =	USB_DT_CS_INTERFACE,
	.bDescriptorSubType =	USB_CDC_UNION_TYPE,
};

struct usb_cdc_ether_desc 		eth_ether_desc = {
	.bLength =		sizeof(struct usb_cdc_ether_desc),
	.bDescriptorType =	USB_DT_CS_INTERFACE,
	.bDescriptorSubType =	USB_CDC_ETHERNET_TYPE,
	
	.bmEthernetStatistics =	__constant_cpu_to_le32(0), 
	.wMaxSegmentSize =	__constant_cpu_to_le16(ETH_FRAME_LEN),
	.wNumberMCFilters =	__constant_cpu_to_le16(0),
	.bNumberPowerFilters =	0,
};

struct usb_endpoint_descriptor 		eth_control_intf_hs_int_in_ep_desc = {
	.bDescriptorType =      USB_DT_ENDPOINT,
	.bLength =              USB_DT_ENDPOINT_SIZE,
	.bEndpointAddress =     USB_DIR_IN,
	.bmAttributes =         USB_ENDPOINT_XFER_INT,
	.bInterval =           4,
	.wMaxPacketSize =       64,
};

struct usb_endpoint_descriptor 		eth_control_intf_fs_int_in_ep_desc = {
Exemplo n.º 5
0
/* how many of the uframe's 125 usecs are allocated? */
static unsigned short
periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
{
	__le32			*hw_p = &ehci->periodic [frame];
	union ehci_shadow	*q = &ehci->pshadow [frame];
	unsigned		usecs = 0;

	while (q->ptr) {
		switch (Q_NEXT_TYPE (*hw_p)) {
		case Q_TYPE_QH:
			/* is it in the S-mask? */
			if (q->qh->hw_info2 & cpu_to_le32 (1 << uframe))
				usecs += q->qh->usecs;
			/* ... or C-mask? */
			if (q->qh->hw_info2 & cpu_to_le32 (1 << (8 + uframe)))
				usecs += q->qh->c_usecs;
			hw_p = &q->qh->hw_next;
			q = &q->qh->qh_next;
			break;
		case Q_TYPE_FSTN:
			/* for "save place" FSTNs, count the relevant INTR
			 * bandwidth from the previous frame
			 */
			if (q->fstn->hw_prev != EHCI_LIST_END) {
				ehci_dbg (ehci, "ignoring FSTN cost ...\n");
			}
			hw_p = &q->fstn->hw_next;
			q = &q->fstn->fstn_next;
			break;
		case Q_TYPE_ITD:
			usecs += q->itd->usecs [uframe];
			hw_p = &q->itd->hw_next;
			q = &q->itd->itd_next;
			break;
		case Q_TYPE_SITD:
			/* is it in the S-mask?  (count SPLIT, DATA) */
			if (q->sitd->hw_uframe & cpu_to_le32 (1 << uframe)) {
				if (q->sitd->hw_fullspeed_ep &
						__constant_cpu_to_le32 (1<<31))
					usecs += q->sitd->stream->usecs;
				else	/* worst case for OUT start-split */
					usecs += HS_USECS_ISO (188);
			}

			/* ... C-mask?  (count CSPLIT, DATA) */
			if (q->sitd->hw_uframe &
					cpu_to_le32 (1 << (8 + uframe))) {
				/* worst case for IN complete-split */
				usecs += q->sitd->stream->c_usecs;
			}

			hw_p = &q->sitd->hw_next;
			q = &q->sitd->sitd_next;
			break;
		default:
			BUG ();
		}
	}
#ifdef	DEBUG
	if (usecs > 100)
		err ("overallocated uframe %d, periodic is %d usecs",
			frame * 8 + uframe, usecs);
#endif
	return usecs;
}
Exemplo n.º 6
0
#include <linux/fs.h>
#include <linux/slab.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsacl.h"
#include "cifsproto.h"
#include "cifs_debug.h"


#ifdef CONFIG_CIFS_EXPERIMENTAL

static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
	{{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
	{{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
	{{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
	{{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(544), 0, 0, 0} }, "root"},
	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(545), 0, 0, 0} }, "users"},
	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(546), 0, 0, 0} }, "guest"} }
;


/* security id for everyone */
static const struct cifs_sid sid_everyone = {
	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
/* group users */
static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };


int match_sid(struct cifs_sid *ctsid)
Exemplo n.º 7
0
int showtraffic()
{
	struct iwreq wrq;
	int sfd, ret, i;
	unsigned long long rxtotal = 0;
	unsigned long long txtotal = 0;
	RT_MBSS_STATISTICS_TABLE stable2G;
	RT_MBSS_STATISTICS_TABLE stable5G;
	unsigned int amount = 0;
	FILE *fp = NULL;
	char ifname2G[32] = {0};
	char ifname5G[32] = {0};

	tcapi_get_string("WLan_Common", "wl0_ifname", ifname2G);

	if(ifname2G[0] == '\0' )
	{
		printf("[iwpriv.c]there is no 2G WiFi interface name\n");
		return -1;
	}

	fp = fopen(WIFI_TRAFFIC_PATH, "w");
	if(!fp)
	{
		printf("[iwpriv.c]Cannot write to file:%s\n", WIFI_TRAFFIC_PATH);
		return -2;
	}

	sfd = socket(AF_INET, SOCK_DGRAM,0);
	memset(&stable2G, 0, sizeof(RT_MBSS_STATISTICS_TABLE));
	wrq.u.data.flags = OID_802_11_STATISTICS;
	strcpy(wrq.ifr_name, ifname2G);
	wrq.u.data.length = sizeof(stable2G);
	wrq.u.data.pointer = &stable2G;
	ret = ioctl(sfd, RT_PRIV_IOCTL, &wrq);

	rxtotal = 0;
	txtotal = 0;
	amount = __constant_cpu_to_le32(stable2G.Num);

#ifdef TCSUPPORT_WLAN_RT6856
#else
	if( amount > 4 )
	{
		amount = 4;
	}
#endif

	if (!ret) {
		printf("\t");
		fprintf(fp, "\t");
		for (i = 0; i < amount; i++)
		{
			printf("mssid_%d\t", i);
			fprintf(fp, "mssid_%d\t", i);
		}
		printf("TotalCount\n");
		fprintf(fp, "TotalCount\n");
		
		printf("2GRxCount:");
		fprintf(fp, "2GRxCount:");
		for (i = 0; i < amount; i++)
		{
			printf("%u\t", __constant_le32_to_cpu(stable2G.MbssEntry[i].ReceivedByteCount));
			fprintf(fp, "%u\t", __constant_le32_to_cpu(stable2G.MbssEntry[i].ReceivedByteCount));
			rxtotal += __constant_le32_to_cpu(stable2G.MbssEntry[i].ReceivedByteCount);
		}
		printf("%llu\n", rxtotal);
		fprintf(fp, "%llu\n", rxtotal);

		printf("2GTxCount:");
		fprintf(fp, "2GTxCount:");
		for (i = 0; i < amount; i++)
		{
			printf("%u\t", __constant_le32_to_cpu(stable2G.MbssEntry[i].TransmittedByteCount));
			fprintf(fp, "%u\t", __constant_le32_to_cpu(stable2G.MbssEntry[i].TransmittedByteCount));
			txtotal += __constant_le32_to_cpu(stable2G.MbssEntry[i].TransmittedByteCount);
		}
		printf("%llu\n", txtotal);
		fprintf(fp, "%llu\n", txtotal);
	}

	tcapi_get_string("WLan_Common", "wl1_ifname", ifname5G);
	if(ifname5G[0] == '\0' )
	{
		//printf("[iwpriv.c]has no 5G WiFi interface\n");
		fclose(fp);
		close(sfd);
		return 1;
	}

	memset(&stable5G, 0, sizeof(RT_MBSS_STATISTICS_TABLE));
	strcpy(wrq.ifr_name, ifname5G);
	wrq.u.data.pointer = &stable5G;
	ret = ioctl(sfd, RT_PRIV_IOCTL, &wrq);

	rxtotal = 0;
	txtotal = 0;
	amount = __constant_cpu_to_le32(stable5G.Num);

#ifdef TCSUPPORT_WLAN_RT6856
#else
	if( amount > 4 )
	{
		amount = 4;
	}
#endif

	if (!ret) {
		printf("5GRxCount:");
		fprintf(fp, "5GRxCount:");
		for (i = 0; i < amount; i++)
		{
			printf("%u\t", __constant_le32_to_cpu(stable5G.MbssEntry[i].ReceivedByteCount));
			fprintf(fp, "%u\t", __constant_le32_to_cpu(stable5G.MbssEntry[i].ReceivedByteCount));
			rxtotal += __constant_le32_to_cpu(stable5G.MbssEntry[i].ReceivedByteCount);
		}
		printf("%llu\n", rxtotal);
		fprintf(fp, "%llu\n", rxtotal);

		printf("5GTxCount:");
		fprintf(fp, "5GTxCount:");
		for (i = 0; i < amount; i++)
		{
			printf("%u\t", __constant_le32_to_cpu(stable5G.MbssEntry[i].TransmittedByteCount));
			fprintf(fp, "%u\t", __constant_le32_to_cpu(stable5G.MbssEntry[i].TransmittedByteCount));
			txtotal += __constant_le32_to_cpu(stable5G.MbssEntry[i].TransmittedByteCount);
		}
		printf("%llu\n", txtotal);
		fprintf(fp, "%llu\n", txtotal);
	}

	fclose(fp);
	close(sfd);
	return 0;
}
Exemplo n.º 8
0
			return ITEM_FOUND;	/* Key found in the array.  */
		}

	/* bin_search did not find given key, it returns position of key,
	   that is minimal and greater than the given one. */
	*pos = lbound;
	return ITEM_NOT_FOUND;
}


/* Minimal possible key. It is never in the tree. */
const struct reiserfs_key MIN_KEY = { 0, 0, {{0, 0},} };

/* Maximal possible key. It is never in the tree. */
static const struct reiserfs_key MAX_KEY = {
	__constant_cpu_to_le32(0xffffffff),
	__constant_cpu_to_le32(0xffffffff),
	{{__constant_cpu_to_le32(0xffffffff),
	  __constant_cpu_to_le32(0xffffffff)},}
};

/* Get delimiting key of the buffer by looking for it in the buffers in the path, starting from the bottom
   of the path, and going upwards.  We must check the path's validity at each step.  If the key is not in
   the path, there is no delimiting key in the tree (buffer is first or last buffer in tree), and in this
   case we return a special key, either MIN_KEY or MAX_KEY. */
static inline const struct reiserfs_key *get_lkey(const struct treepath *chk_path,
						  const struct super_block *sb)
{
	int position, path_offset = chk_path->path_length;
	struct buffer_head *parent;
Exemplo n.º 9
0
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/keyctl.h>
#include <linux/key-type.h>
#include <keys/user-type.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsacl.h"
#include "cifsproto.h"
#include "cifs_debug.h"

static const struct cifs_sid sid_everyone = {
	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
static const struct cifs_sid sid_authusers = {
	1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11)} };
static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };

const struct cred *root_cred;

static void
shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem,
			int *nr_del)
{
	struct rb_node *node;
	struct rb_node *tmp;
	struct cifs_sid_id *psidid;

	node = rb_first(root);
	while (node) {
		tmp = node;
Exemplo n.º 10
0
 * i2400ms_rx_setup()
 *
 * i2400ms_rx_release()
 */
#include <linux/workqueue.h>
#include <linux/wait.h>
#include <linux/skbuff.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h>
#include "i2400m-sdio.h"

#define D_SUBMODULE rx
#include "sdio-debug-levels.h"

static const __le32 i2400m_ACK_BARKER[4] = {
	__constant_cpu_to_le32(I2400M_ACK_BARKER),
	__constant_cpu_to_le32(I2400M_ACK_BARKER),
	__constant_cpu_to_le32(I2400M_ACK_BARKER),
	__constant_cpu_to_le32(I2400M_ACK_BARKER)
};


/*
 * Read and return the amount of bytes available for RX
 *
 * The RX size has to be read like this: byte reads of three
 * sequential locations; then glue'em together.
 *
 * sdio_readl() doesn't work.
 */
ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms)
Exemplo n.º 11
0
static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
{
	struct sk_buff *skb;
	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
	int len;
	int nframes;
	int x;
	int offset;
	struct usb_cdc_ncm_ndp16 *ndp16;
	struct usb_cdc_ncm_dpe16 *dpe16;
	int ndpoffset;
	int loopcount = 50; /* arbitrary max preventing infinite loop */

	ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in);
	if (ndpoffset < 0)
		goto error;

next_ndp:
	nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset);
	if (nframes < 0)
		goto error;

	ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset);

	if (ndp16->dwSignature != __constant_cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) {
		pr_debug("invalid DPT16 signature <%#010x>\n",
			 le32_to_cpu(ndp16->dwSignature));
		goto err_ndp;
	}
	dpe16 = ndp16->dpe16;

	for (x = 0; x < nframes; x++, dpe16++) {
		offset = le16_to_cpu(dpe16->wDatagramIndex);
		len = le16_to_cpu(dpe16->wDatagramLength);

		/*
		 * CDC NCM ch. 3.7
		 * All entries after first NULL entry are to be ignored
		 */
		if ((offset == 0) || (len == 0)) {
			if (!x)
				goto err_ndp; /* empty NTB */
			break;
		}

		/* sanity checking */
		if (((offset + len) > skb_in->len) ||
				(len > ctx->rx_max) || (len < ETH_HLEN)) {
			pr_debug("invalid frame detected (ignored)"
					"offset[%u]=%u, length=%u, skb=%p\n",
					x, offset, len, skb_in);
			if (!x)
				goto err_ndp;
			break;

		} else {
			skb = skb_clone(skb_in, GFP_ATOMIC);
			if (!skb)
				goto error;
			skb->len = len;
			skb->data = ((u8 *)skb_in->data) + offset;
			skb_set_tail_pointer(skb, len);
			usbnet_skb_return(dev, skb);
		}
	}
err_ndp:
	/* are there more NDPs to process? */
	ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex);
	if (ndpoffset && loopcount--)
		goto next_ndp;

	return 1;
error:
	return 0;
}
Exemplo n.º 12
0
/*
 * Process completed qtds for a qh, issuing completions if needed.
 * When freeing:  frees qtds, unmaps buf, returns URB to driver.
 * When not freeing (queued periodic qh):  retain qtds, mapping, and urb.
 * Races up to qh->hw_current; returns number of urb completions.
 */
static int
qh_completions (
	struct ehci_hcd		*ehci,
	struct ehci_qh		*qh,
	int			freeing
) {
	struct ehci_qtd		*qtd, *last;
	struct list_head	*next, *qtd_list = &qh->qtd_list;
	int			unlink = 0, halted = 0;
	unsigned long		flags;
	int			retval = 0;

	spin_lock_irqsave (&ehci->lock, flags);
	if (unlikely (list_empty (qtd_list))) {
		spin_unlock_irqrestore (&ehci->lock, flags);
		return retval;
	}

	/* scan QTDs till end of list, or we reach an active one */
	for (qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list),
			    	last = 0, next = 0;
			next != qtd_list;
			last = qtd, qtd = list_entry (next,
						struct ehci_qtd, qtd_list)) {
		struct urb	*urb = qtd->urb;
		u32		token = 0;

		/* clean up any state from previous QTD ...*/
		if (last) {
			if (likely (last->urb != urb)) {
				/* complete() can reenter this HCD */
				spin_unlock_irqrestore (&ehci->lock, flags);
				if (likely (freeing != 0))
					ehci_urb_done (ehci, last->buf_dma,
						last->urb);
				else
					ehci_urb_complete (ehci, last->buf_dma,
						last->urb);
				spin_lock_irqsave (&ehci->lock, flags);
				retval++;
			}

			/* qh overlays can have HC's old cached copies of
			 * next qtd ptrs, if an URB was queued afterwards.
			 */
			if (cpu_to_le32 (last->qtd_dma) == qh->hw_current
					&& last->hw_next != qh->hw_qtd_next) {
				qh->hw_alt_next = last->hw_alt_next;
				qh->hw_qtd_next = last->hw_next;
			}

			if (likely (freeing != 0))
				ehci_qtd_free (ehci, last);
			last = 0;
		}
		next = qtd->qtd_list.next;

		/* QTDs at tail may be active if QH+HC are running,
		 * or when unlinking some urbs queued to this QH
		 */
		token = le32_to_cpu (qtd->hw_token);
		halted = halted
			|| (__constant_cpu_to_le32 (QTD_STS_HALT)
				& qh->hw_token) != 0
			|| (ehci->hcd.state == USB_STATE_HALT)
			|| (qh->qh_state == QH_STATE_IDLE);

		/* fault: unlink the rest, since this qtd saw an error? */
		if (unlikely ((token & QTD_STS_HALT) != 0)) {
			freeing = unlink = 1;
			/* status copied below */

		/* QH halts only because of fault (above) or unlink (here). */
		} else if (unlikely (halted != 0)) {

			/* unlinking everything because of HC shutdown? */
			if (ehci->hcd.state == USB_STATE_HALT) {
				freeing = unlink = 1;

			/* explicit unlink, maybe starting here? */
			} else if (qh->qh_state == QH_STATE_IDLE
					&& (urb->status == -ECONNRESET
						|| urb->status == -ENOENT)) {
				freeing = unlink = 1;

			/* QH halted to unlink urbs _after_ this?  */
			} else if (!unlink && (token & QTD_STS_ACTIVE) != 0) {
				qtd = 0;
				continue;
			}

			/* unlink the rest?  once we start unlinking, after
			 * a fault or explicit unlink, we unlink all later
			 * urbs.  usb spec requires that.
			 */
			if (unlink && urb->status == -EINPROGRESS)
				urb->status = -ECONNRESET;

		/* Else QH is active, so we must not modify QTDs
		 * that HC may be working on.  No more qtds to check.
		 */
		} else if (unlikely ((token & QTD_STS_ACTIVE) != 0)) {
			next = qtd_list;
			qtd = 0;
			continue;
		}

		spin_lock (&urb->lock);
		qtd_copy_status (urb, qtd->length, token);
		spin_unlock (&urb->lock);

		/*
		 * NOTE:  this won't work right with interrupt urbs that
		 * need multiple qtds ... only the first scan of qh->qtd_list
		 * starts at the right qtd, yet multiple scans could happen
		 * for transfers that are scheduled across multiple uframes. 
		 * (Such schedules are not currently allowed!)
		 */
		if (likely (freeing != 0))
			list_del (&qtd->qtd_list);
		else {
			/* restore everything the HC could change
			 * from an interrupt QTD
			 */
			qtd->hw_token = (qtd->hw_token
					& __constant_cpu_to_le32 (0x8300))
				| cpu_to_le32 (qtd->length << 16)
				| __constant_cpu_to_le32 (QTD_STS_ACTIVE
					| (EHCI_TUNE_CERR << 10));
			qtd->hw_buf [0] &= ~__constant_cpu_to_le32 (0x0fff);

			/* this offset, and the length above,
			 * are likely wrong on QTDs #2..N
			 */
			qtd->hw_buf [0] |= cpu_to_le32 (0x0fff & qtd->buf_dma);
		}

#if 0
		if (urb->status == -EINPROGRESS)
			vdbg ("  qtd %p ok, urb %p, token %8x, len %d",
				qtd, urb, token, urb->actual_length);
		else
			vdbg ("urb %p status %d, qtd %p, token %8x, len %d",
				urb, urb->status, qtd, token,
				urb->actual_length);
#endif

		/* SETUP for control urb? */
		if (unlikely (QTD_PID (token) == 2))
			pci_unmap_single (ehci->hcd.pdev,
				qtd->buf_dma, sizeof (devrequest),
				PCI_DMA_TODEVICE);
	}

	/* patch up list head? */
	if (unlikely (halted && !list_empty (qtd_list))) {
		qh_update (qh, list_entry (qtd_list->next,
				struct ehci_qtd, qtd_list));
	}
Exemplo n.º 13
0
/**
 * qla2x00_build_scsi_iocbs_64() - Build IOCB command utilizing 64bit
 * capable IOCB types.
 *
 * @sp: SRB command to process
 * @cmd_pkt: Command type 3 IOCB
 * @tot_dsds: Total number of segments to transfer
 */
void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
    uint16_t tot_dsds)
{
	uint16_t	avail_dsds;
	uint32_t	*cur_dsd;
	scsi_qla_host_t	*ha;
	struct scsi_cmnd *cmd;

	cmd = sp->cmd;

	/* Update entry type to indicate Command Type 3 IOCB */
	*((uint32_t *)(&cmd_pkt->entry_type)) =
	    __constant_cpu_to_le32(COMMAND_A64_TYPE);

	/* No data transfer */
	if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) {
		cmd_pkt->byte_count = __constant_cpu_to_le32(0);
		return;
	}

	ha = sp->ha;

	cmd_pkt->control_flags |= cpu_to_le16(qla2x00_get_cmd_direction(cmd));

	/* Two DSDs are available in the Command Type 3 IOCB */
	avail_dsds = 2;
	cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;

	/* Load data segments */
	if (cmd->use_sg != 0) {
		struct	scatterlist *cur_seg;
		struct	scatterlist *end_seg;

		cur_seg = (struct scatterlist *)cmd->request_buffer;
		end_seg = cur_seg + tot_dsds;
		while (cur_seg < end_seg) {
			dma_addr_t	sle_dma;
			cont_a64_entry_t *cont_pkt;

			/* Allocate additional continuation packets? */
			if (avail_dsds == 0) {
				/*
				 * Five DSDs are available in the Continuation
				 * Type 1 IOCB.
				 */
				cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
				cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
				avail_dsds = 5;
			}

			sle_dma = sg_dma_address(cur_seg);
			*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
			*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
			*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
			avail_dsds--;

			cur_seg++;
		}
	} else {
		dma_addr_t	req_dma;
		struct page	*page;
		unsigned long	offset;

		page = virt_to_page(cmd->request_buffer);
		offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
		req_dma = pci_map_page(ha->pdev, page, offset,
		    cmd->request_bufflen, cmd->sc_data_direction);

		sp->dma_handle = req_dma;

		*cur_dsd++ = cpu_to_le32(LSD(req_dma));
		*cur_dsd++ = cpu_to_le32(MSD(req_dma));
		*cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
	}
}
Exemplo n.º 14
0
/**
 * qla24xx_build_scsi_iocbs() - Build IOCB command utilizing Command Type 7
 * IOCB types.
 *
 * @sp: SRB command to process
 * @cmd_pkt: Command type 3 IOCB
 * @tot_dsds: Total number of segments to transfer
 */
static inline void
qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
                         uint16_t tot_dsds)
{
    uint16_t	avail_dsds;
    uint32_t	*cur_dsd;
    scsi_qla_host_t	*ha;
    struct scsi_cmnd *cmd;

    cmd = sp->cmd;

    /* Update entry type to indicate Command Type 3 IOCB */
    *((uint32_t *)(&cmd_pkt->entry_type)) =
        __constant_cpu_to_le32(COMMAND_TYPE_7);

    /* No data transfer */
    if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) {
        cmd_pkt->byte_count = __constant_cpu_to_le32(0);
        return;
    }

    ha = sp->ha;

    /* Set transfer direction */
    if (cmd->sc_data_direction == DMA_TO_DEVICE)
        cmd_pkt->task_mgmt_flags =
            __constant_cpu_to_le16(TMF_WRITE_DATA);
    else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
        cmd_pkt->task_mgmt_flags =
            __constant_cpu_to_le16(TMF_READ_DATA);

    /* One DSD is available in the Command Type 3 IOCB */
    avail_dsds = 1;
    cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;

    /* Load data segments */
    if (cmd->use_sg != 0) {
        struct	scatterlist *cur_seg;
        struct	scatterlist *end_seg;

        cur_seg = (struct scatterlist *)cmd->request_buffer;
        end_seg = cur_seg + tot_dsds;
        while (cur_seg < end_seg) {
            dma_addr_t	sle_dma;
            cont_a64_entry_t *cont_pkt;

            /* Allocate additional continuation packets? */
            if (avail_dsds == 0) {
                /*
                 * Five DSDs are available in the Continuation
                 * Type 1 IOCB.
                 */
                cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
                cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
                avail_dsds = 5;
            }

            sle_dma = sg_dma_address(cur_seg);
            *cur_dsd++ = cpu_to_le32(LSD(sle_dma));
            *cur_dsd++ = cpu_to_le32(MSD(sle_dma));
            *cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
            avail_dsds--;

            cur_seg++;
        }
    } else {
        *cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
        *cur_dsd++ = cpu_to_le32(MSD(sp->dma_handle));
        *cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
    }
}