} 
static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw){	struct orinoco_private *priv = netdev_priv(dev);	u16 infofid;	struct {		u16 len;		u16 type;	} __attribute__ ((packed)) info;	int len, type;	int err;	/* This is an answer to an INQUIRE command that we did earlier,	 * or an information "event" generated by the card	 * The controller return to us a pseudo frame containing	 * the information in question - Jean II */	infofid = hermes_read_regn(hw, INFOFID);	/* Read the info frame header - don't try too hard */	err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),			       infofid, 0);	if (err) {		printk(KERN_ERR "%s: error %d reading info frame. "		       "Frame dropped.\n", dev->name, err);		return;	}		len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));	type = le16_to_cpu(info.type);	switch (type) {	case HERMES_INQ_TALLIES: {		struct hermes_tallies_frame tallies;		struct iw_statistics *wstats = &priv->wstats;				if (len > sizeof(tallies)) {			printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",			       dev->name, len);			len = sizeof(tallies);		}				err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,				       infofid, sizeof(info));		if (err)			break;				/* Increment our various counters */		/* wstats->discard.nwid - no wrong BSSID stuff */		wstats->discard.code +=			le16_to_cpu(tallies.RxWEPUndecryptable);		if (len == sizeof(tallies))  			wstats->discard.code +=				le16_to_cpu(tallies.RxDiscards_WEPICVError) +				le16_to_cpu(tallies.RxDiscards_WEPExcluded);		wstats->discard.misc +=			le16_to_cpu(tallies.TxDiscardsWrongSA);		wstats->discard.fragment +=			le16_to_cpu(tallies.RxMsgInBadMsgFragments);		wstats->discard.retries +=			le16_to_cpu(tallies.TxRetryLimitExceeded);		/* wstats->miss.beacon - no match */	}	break;	case HERMES_INQ_LINKSTATUS: {		struct hermes_linkstatus linkstatus;		u16 newstatus;		int connected;		if (priv->iw_mode == IW_MODE_MONITOR)			break;		if (len != sizeof(linkstatus)) {			printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",			       dev->name, len);			break;		}		err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,				       infofid, sizeof(info));		if (err)			break;		newstatus = le16_to_cpu(linkstatus.linkstatus);		/* Symbol firmware uses "out of range" to signal that		 * the hostscan frame can be requested.  */		if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&		    priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&		    priv->has_hostscan && priv->scan_inprogress) {			hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);			break;		}		connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)			|| (newstatus == HERMES_LINKSTATUS_AP_CHANGE)			|| (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);		if (connected)			netif_carrier_on(dev);		else if (!ignore_disconnect)			netif_carrier_off(dev);		if (newstatus != priv->last_linkstatus) {			priv->last_linkstatus = newstatus;			print_linkstatus(dev, newstatus);			/* The info frame contains only one word which is the			 * status (see hermes.h). The status is pretty boring			 * in itself, that's why we export the new BSSID...			 * Jean II */			schedule_work(&priv->wevent_work);		}	}	break;	case HERMES_INQ_SCAN:		if (!priv->scan_inprogress && priv->bssid_fixed &&		    priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {			schedule_work(&priv->join_work);			break;		}		/* fall through */	case HERMES_INQ_HOSTSCAN:	case HERMES_INQ_HOSTSCAN_SYMBOL: {		/* Result of a scanning. Contains information about		 * cells in the vicinity - Jean II */		union iwreq_data	wrqu;		unsigned char *buf;		/* Sanity check */		if (len > 4096) {			printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",			       dev->name, len);			break;		}		/* We are a strict producer. If the previous scan results		 * have not been consumed, we just have to drop this		 * frame. We can't remove the previous results ourselves,		 * that would be *very* racy... Jean II */		if (priv->scan_result != NULL) {			printk(KERN_WARNING "%s: Previous scan results not consumed, dropping info frame.\n", dev->name);			break;		}		/* Allocate buffer for results */		buf = kmalloc(len, GFP_ATOMIC);		if (buf == NULL)			/* No memory, so can't printk()... */			break;		/* Read scan data */		err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,				       infofid, sizeof(info));		if (err)			break;#ifdef ORINOCO_DEBUG		{			int	i;			printk(KERN_DEBUG "Scan result [%02X", buf[0]);			for(i = 1; i < (len * 2); i++)				printk(":%02X", buf[i]);			printk("]\n");		}#endif	/* ORINOCO_DEBUG */		/* Allow the clients to access the results */		priv->scan_len = len;		priv->scan_result = buf;		/* Send an empty event to user space.		 * We don't send the received data on the event because		 * it would require us to do complex transcoding, and		 * we want to minimise the work done in the irq handler		 * Use a request to extract the data - Jean II */		wrqu.data.length = 0;		wrqu.data.flags = 0;		wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);	}	break;	case HERMES_INQ_SEC_STAT_AGERE:		/* Security status (Agere specific) */		/* Ignore this frame for now */		if (priv->firmware_type == FIRMWARE_TYPE_AGERE)			break;		/* fall through */	default:		printk(KERN_DEBUG "%s: Unknown information frame received: "		       "type 0x%04x, length %d\n", dev->name, type, len);		/* We don't actually do anything about it */		break;	}}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/708218b064e3ad3d55ac0f9d19b3c8c0fb7af3a4/orinoco.c/buggy/drivers/net/wireless/orinoco.c