Esempio n. 1
0
static int __init ircomm_init(void)
{
	ircomm = hashbin_new(HB_LOCK);
	if (ircomm == NULL) {
		IRDA_ERROR("%s(), can't allocate hashbin!\n", __FUNCTION__);
		return -ENOMEM;
	}

#ifdef CONFIG_PROC_FS
	{ struct proc_dir_entry *ent;
	ent = create_proc_entry("ircomm", 0, proc_irda);
	if (ent)
		ent->proc_fops = &ircomm_proc_fops;
	}
#endif /* CONFIG_PROC_FS */

	IRDA_MESSAGE("IrCOMM protocol (Dag Brattli)\n");

	return 0;
}
static int __init ircomm_init(void)
{
    ircomm = hashbin_new(HB_LOCK);
    if (ircomm == NULL) {
        IRDA_ERROR("%s(), can't allocate hashbin!\n", __func__);
        return -ENOMEM;
    }

#ifdef CONFIG_PROC_FS
    {   struct proc_dir_entry *ent;
        ent = proc_create("ircomm", 0, proc_irda, &ircomm_proc_fops);
        if (!ent) {
            printk(KERN_ERR "ircomm_init: can't create /proc entry!\n");
            return -ENODEV;
        }
    }
#endif

    IRDA_MESSAGE("IrCOMM protocol (Dag Brattli)\n");

    return 0;
}
Esempio n. 3
0
static int w83977af_probe(int iobase, int irq, int dma)
{
  	int version;
	int i;
  	
 	for (i=0; i < 2; i++) {
		IRDA_DEBUG( 0, "%s()\n", __func__ );
#ifdef CONFIG_USE_W977_PNP
 		/* Enter PnP configuration mode */
		w977_efm_enter(efbase[i]);
  
 		w977_select_device(W977_DEVICE_IR, efbase[i]);
  
 		/* Configure PnP port, IRQ, and DMA channel */
 		w977_write_reg(0x60, (iobase >> 8) & 0xff, efbase[i]);
 		w977_write_reg(0x61, (iobase) & 0xff, efbase[i]);
  
 		w977_write_reg(0x70, irq, efbase[i]);
#ifdef CONFIG_ARCH_NETWINDER
		/* Netwinder uses 1 higher than Linux */
 		w977_write_reg(0x74, dma+1, efbase[i]);
#else
 		w977_write_reg(0x74, dma, efbase[i]);   
#endif /*CONFIG_ARCH_NETWINDER */
 		w977_write_reg(0x75, 0x04, efbase[i]);  /* Disable Tx DMA */
  	
 		/* Set append hardware CRC, enable IR bank selection */	
 		w977_write_reg(0xf0, APEDCRC|ENBNKSEL, efbase[i]);
  
 		/* Activate device */
 		w977_write_reg(0x30, 0x01, efbase[i]);
  
 		w977_efm_exit(efbase[i]);
#endif /* CONFIG_USE_W977_PNP */
  		/* Disable Advanced mode */
  		switch_bank(iobase, SET2);
  		outb(iobase+2, 0x00);  
 
 		/* Turn on UART (global) interrupts */
 		switch_bank(iobase, SET0);
  		outb(HCR_EN_IRQ, iobase+HCR);
  	
  		/* Switch to advanced mode */
  		switch_bank(iobase, SET2);
  		outb(inb(iobase+ADCR1) | ADCR1_ADV_SL, iobase+ADCR1);
  
  		/* Set default IR-mode */
  		switch_bank(iobase, SET0);
  		outb(HCR_SIR, iobase+HCR);
  
  		/* Read the Advanced IR ID */
  		switch_bank(iobase, SET3);
  		version = inb(iobase+AUID);
  	
  		/* Should be 0x1? */
  		if (0x10 == (version & 0xf0)) {
 			efio = efbase[i];
 
 			/* Set FIFO size to 32 */
 			switch_bank(iobase, SET2);
 			outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);	
 	
 			/* Set FIFO threshold to TX17, RX16 */
 			switch_bank(iobase, SET0);	
 			outb(UFR_RXTL|UFR_TXTL|UFR_TXF_RST|UFR_RXF_RST|
			     UFR_EN_FIFO,iobase+UFR);
 
 			/* Receiver frame length */
 			switch_bank(iobase, SET4);
			outb(2048 & 0xff, iobase+6);
			outb((2048 >> 8) & 0x1f, iobase+7);

			/* 
			 * Init HP HSDL-1100 transceiver. 
			 * 
			 * Set IRX_MSL since we have 2 * receive paths IRRX, 
			 * and IRRXH. Clear IRSL0D since we want IRSL0 * to 
			 * be a input pin used for IRRXH 
			 *
			 *   IRRX  pin 37 connected to receiver 
			 *   IRTX  pin 38 connected to transmitter
			 *   FIRRX pin 39 connected to receiver      (IRSL0) 
			 *   CIRRX pin 40 connected to pin 37
			 */
			switch_bank(iobase, SET7);
			outb(0x40, iobase+7);
			
			IRDA_MESSAGE("W83977AF (IR) driver loaded. "
				     "Version: 0x%02x\n", version);
			
			return 0;
		} else {
Esempio n. 4
0
/*
 * Function w83977af_open (iobase, irq)
 *
 *    Open driver instance
 *
 */
static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
			 unsigned int dma)
{
	struct net_device *dev;
        struct w83977af_ir *self;
	int err;

	IRDA_DEBUG(0, "%s()\n", __func__ );

	/* Lock the port that we need */
	if (!request_region(iobase, CHIP_IO_EXTENT, driver_name)) {
		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
		      __func__ , iobase);
		return -ENODEV;
	}

	if (w83977af_probe(iobase, irq, dma) == -1) {
		err = -1;
		goto err_out;
	}
	/*
	 *  Allocate new instance of the driver
	 */
	dev = alloc_irdadev(sizeof(struct w83977af_ir));
	if (dev == NULL) {
		printk( KERN_ERR "IrDA: Can't allocate memory for "
			"IrDA control block!\n");
		err = -ENOMEM;
		goto err_out;
	}

	self = netdev_priv(dev);
	spin_lock_init(&self->lock);
   

	/* Initialize IO */
	self->io.fir_base   = iobase;
        self->io.irq       = irq;
        self->io.fir_ext   = CHIP_IO_EXTENT;
        self->io.dma       = dma;
        self->io.fifo_size = 32;

	/* Initialize QoS for this device */
	irda_init_max_qos_capabilies(&self->qos);
	
	/* The only value we must override it the baudrate */

	/* FIXME: The HP HDLS-1100 does not support 1152000! */
	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);

	/* The HP HDLS-1100 needs 1 ms according to the specs */
	self->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&self->qos);
	
	/* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
	self->rx_buff.truesize = 14384; 
	self->tx_buff.truesize = 4000;
	
	/* Allocate memory if needed */
	self->rx_buff.head =
		dma_alloc_coherent(NULL, self->rx_buff.truesize,
				   &self->rx_buff_dma, GFP_KERNEL);
	if (self->rx_buff.head == NULL) {
		err = -ENOMEM;
		goto err_out1;
	}

	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
	
	self->tx_buff.head =
		dma_alloc_coherent(NULL, self->tx_buff.truesize,
				   &self->tx_buff_dma, GFP_KERNEL);
	if (self->tx_buff.head == NULL) {
		err = -ENOMEM;
		goto err_out2;
	}
	memset(self->tx_buff.head, 0, self->tx_buff.truesize);

	self->rx_buff.in_frame = FALSE;
	self->rx_buff.state = OUTSIDE_FRAME;
	self->tx_buff.data = self->tx_buff.head;
	self->rx_buff.data = self->rx_buff.head;
	self->netdev = dev;

	dev->netdev_ops	= &w83977_netdev_ops;

	err = register_netdev(dev);
	if (err) {
		IRDA_ERROR("%s(), register_netdevice() failed!\n", __func__);
		goto err_out3;
	}
	IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name);

	/* Need to store self somewhere */
	dev_self[i] = self;
	
	return 0;
err_out3:
	dma_free_coherent(NULL, self->tx_buff.truesize,
			  self->tx_buff.head, self->tx_buff_dma);
err_out2:	
	dma_free_coherent(NULL, self->rx_buff.truesize,
			  self->rx_buff.head, self->rx_buff_dma);
err_out1:
	free_netdev(dev);
err_out:
	release_region(iobase, CHIP_IO_EXTENT);
	return err;
}
static int w83977af_probe(int iobase, int irq, int dma)
{
  	int version;
	int i;
  	
 	for (i=0; i < 2; i++) {
		IRDA_DEBUG( 0, "%s()\n", __func__ );
#ifdef CONFIG_USE_W977_PNP
 		
		w977_efm_enter(efbase[i]);
  
 		w977_select_device(W977_DEVICE_IR, efbase[i]);
  
 		
 		w977_write_reg(0x60, (iobase >> 8) & 0xff, efbase[i]);
 		w977_write_reg(0x61, (iobase) & 0xff, efbase[i]);
  
 		w977_write_reg(0x70, irq, efbase[i]);
#ifdef CONFIG_ARCH_NETWINDER
		
 		w977_write_reg(0x74, dma+1, efbase[i]);
#else
 		w977_write_reg(0x74, dma, efbase[i]);   
#endif 
 		w977_write_reg(0x75, 0x04, efbase[i]);  
  	
 			
 		w977_write_reg(0xf0, APEDCRC|ENBNKSEL, efbase[i]);
  
 		
 		w977_write_reg(0x30, 0x01, efbase[i]);
  
 		w977_efm_exit(efbase[i]);
#endif 
  		
  		switch_bank(iobase, SET2);
  		outb(iobase+2, 0x00);  
 
 		
 		switch_bank(iobase, SET0);
  		outb(HCR_EN_IRQ, iobase+HCR);
  	
  		
  		switch_bank(iobase, SET2);
  		outb(inb(iobase+ADCR1) | ADCR1_ADV_SL, iobase+ADCR1);
  
  		
  		switch_bank(iobase, SET0);
  		outb(HCR_SIR, iobase+HCR);
  
  		
  		switch_bank(iobase, SET3);
  		version = inb(iobase+AUID);
  	
  		
  		if (0x10 == (version & 0xf0)) {
 			efio = efbase[i];
 
 			
 			switch_bank(iobase, SET2);
 			outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);	
 	
 			
 			switch_bank(iobase, SET0);	
 			outb(UFR_RXTL|UFR_TXTL|UFR_TXF_RST|UFR_RXF_RST|
			     UFR_EN_FIFO,iobase+UFR);
 
 			
 			switch_bank(iobase, SET4);
			outb(2048 & 0xff, iobase+6);
			outb((2048 >> 8) & 0x1f, iobase+7);

			switch_bank(iobase, SET7);
			outb(0x40, iobase+7);
			
			IRDA_MESSAGE("W83977AF (IR) driver loaded. "
				     "Version: 0x%02x\n", version);
			
			return 0;
		} else {
static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
			 unsigned int dma)
{
	struct net_device *dev;
        struct w83977af_ir *self;
	int err;

	IRDA_DEBUG(0, "%s()\n", __func__ );

	
	if (!request_region(iobase, CHIP_IO_EXTENT, driver_name)) {
		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
		      __func__ , iobase);
		return -ENODEV;
	}

	if (w83977af_probe(iobase, irq, dma) == -1) {
		err = -1;
		goto err_out;
	}
	dev = alloc_irdadev(sizeof(struct w83977af_ir));
	if (dev == NULL) {
		printk( KERN_ERR "IrDA: Can't allocate memory for "
			"IrDA control block!\n");
		err = -ENOMEM;
		goto err_out;
	}

	self = netdev_priv(dev);
	spin_lock_init(&self->lock);
   

	
	self->io.fir_base   = iobase;
        self->io.irq       = irq;
        self->io.fir_ext   = CHIP_IO_EXTENT;
        self->io.dma       = dma;
        self->io.fifo_size = 32;

	
	irda_init_max_qos_capabilies(&self->qos);
	
	

	
	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);

	
	self->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&self->qos);
	
	
	self->rx_buff.truesize = 14384; 
	self->tx_buff.truesize = 4000;
	
	
	self->rx_buff.head =
		dma_alloc_coherent(NULL, self->rx_buff.truesize,
				   &self->rx_buff_dma, GFP_KERNEL);
	if (self->rx_buff.head == NULL) {
		err = -ENOMEM;
		goto err_out1;
	}

	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
	
	self->tx_buff.head =
		dma_alloc_coherent(NULL, self->tx_buff.truesize,
				   &self->tx_buff_dma, GFP_KERNEL);
	if (self->tx_buff.head == NULL) {
		err = -ENOMEM;
		goto err_out2;
	}
	memset(self->tx_buff.head, 0, self->tx_buff.truesize);

	self->rx_buff.in_frame = FALSE;
	self->rx_buff.state = OUTSIDE_FRAME;
	self->tx_buff.data = self->tx_buff.head;
	self->rx_buff.data = self->rx_buff.head;
	self->netdev = dev;

	dev->netdev_ops	= &w83977_netdev_ops;

	err = register_netdev(dev);
	if (err) {
		IRDA_ERROR("%s(), register_netdevice() failed!\n", __func__);
		goto err_out3;
	}
	IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name);

	
	dev_self[i] = self;
	
	return 0;
err_out3:
	dma_free_coherent(NULL, self->tx_buff.truesize,
			  self->tx_buff.head, self->tx_buff_dma);
err_out2:	
	dma_free_coherent(NULL, self->rx_buff.truesize,
			  self->rx_buff.head, self->rx_buff_dma);
err_out1:
	free_netdev(dev);
err_out:
	release_region(iobase, CHIP_IO_EXTENT);
	return err;
}
static int __init nsc_ircc_open(chipio_t *info)
{
	struct net_device *dev;
	struct nsc_ircc_cb *self;
	void *ret;
	int err, chip_index;

	IRDA_DEBUG(2, "%s()\n", __func__);


 	for (chip_index = 0; chip_index < ARRAY_SIZE(dev_self); chip_index++) {
		if (!dev_self[chip_index])
			break;
	}

	if (chip_index == ARRAY_SIZE(dev_self)) {
		IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __func__);
		return -ENOMEM;
	}

	IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name,
		     info->cfg_base);

	if ((nsc_ircc_setup(info)) == -1)
		return -1;

	IRDA_MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);

	dev = alloc_irdadev(sizeof(struct nsc_ircc_cb));
	if (dev == NULL) {
		IRDA_ERROR("%s(), can't allocate memory for "
			   "control block!\n", __func__);
		return -ENOMEM;
	}

	self = netdev_priv(dev);
	self->netdev = dev;
	spin_lock_init(&self->lock);
   
	
	dev_self[chip_index] = self;
	self->index = chip_index;

	
	self->io.cfg_base  = info->cfg_base;
	self->io.fir_base  = info->fir_base;
        self->io.irq       = info->irq;
        self->io.fir_ext   = CHIP_IO_EXTENT;
        self->io.dma       = info->dma;
        self->io.fifo_size = 32;
	
	
	ret = request_region(self->io.fir_base, self->io.fir_ext, driver_name);
	if (!ret) {
		IRDA_WARNING("%s(), can't get iobase of 0x%03x\n",
			     __func__, self->io.fir_base);
		err = -ENODEV;
		goto out1;
	}

	
	irda_init_max_qos_capabilies(&self->qos);
	
	
	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200|IR_576000|IR_1152000 |(IR_4000000 << 8);
	
	self->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&self->qos);
	
	
	self->rx_buff.truesize = 14384; 
	self->tx_buff.truesize = 14384;

	
	self->rx_buff.head =
		dma_alloc_coherent(NULL, self->rx_buff.truesize,
				   &self->rx_buff_dma, GFP_KERNEL);
	if (self->rx_buff.head == NULL) {
		err = -ENOMEM;
		goto out2;

	}
	memset(self->rx_buff.head, 0, self->rx_buff.truesize);
	
	self->tx_buff.head =
		dma_alloc_coherent(NULL, self->tx_buff.truesize,
				   &self->tx_buff_dma, GFP_KERNEL);
	if (self->tx_buff.head == NULL) {
		err = -ENOMEM;
		goto out3;
	}
	memset(self->tx_buff.head, 0, self->tx_buff.truesize);

	self->rx_buff.in_frame = FALSE;
	self->rx_buff.state = OUTSIDE_FRAME;
	self->tx_buff.data = self->tx_buff.head;
	self->rx_buff.data = self->rx_buff.head;
	
	
	self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
	self->tx_fifo.tail = self->tx_buff.head;

	
	dev->netdev_ops = &nsc_ircc_sir_ops;

	err = register_netdev(dev);
	if (err) {
		IRDA_ERROR("%s(), register_netdev() failed!\n", __func__);
		goto out4;
	}
	IRDA_MESSAGE("IrDA: Registered device %s\n", dev->name);

	
	if ((dongle_id <= 0) ||
	    (dongle_id >= ARRAY_SIZE(dongle_types))) {
		dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base);
		
		IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name,
			     dongle_types[dongle_id]);
	} else {
		IRDA_MESSAGE("%s, Using dongle: %s\n", driver_name,
			     dongle_types[dongle_id]);
	}
	
	self->io.dongle_id = dongle_id;
	nsc_ircc_init_dongle_interface(self->io.fir_base, dongle_id);

 	self->pldev = platform_device_register_simple(NSC_IRCC_DRIVER_NAME,
 						      self->index, NULL, 0);
 	if (IS_ERR(self->pldev)) {
 		err = PTR_ERR(self->pldev);
 		goto out5;
 	}
 	platform_set_drvdata(self->pldev, self);

	return chip_index;

 out5:
 	unregister_netdev(dev);
 out4:
	dma_free_coherent(NULL, self->tx_buff.truesize,
			  self->tx_buff.head, self->tx_buff_dma);
 out3:
	dma_free_coherent(NULL, self->rx_buff.truesize,
			  self->rx_buff.head, self->rx_buff_dma);
 out2:
	release_region(self->io.fir_base, self->io.fir_ext);
 out1:
	free_netdev(dev);
	dev_self[chip_index] = NULL;
	return err;
}
static int __init nsc_ircc_init(void)
{
	chipio_t info;
	nsc_chip_t *chip;
	int ret;
	int cfg_base;
	int cfg, id;
	int reg;
	int i = 0;

	ret = platform_driver_register(&nsc_ircc_driver);
        if (ret) {
                IRDA_ERROR("%s, Can't register driver!\n", driver_name);
                return ret;
        }

 	
	ret = pnp_register_driver(&nsc_ircc_pnp_driver);

 	if (!ret)
 		pnp_registered = 1;

	ret = -ENODEV;

	
	for (chip = chips; chip->name ; chip++) {
		IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __func__,
			   chip->name);
		
		
		for (cfg = 0; cfg < ARRAY_SIZE(chip->cfg); cfg++) {
			cfg_base = chip->cfg[cfg];
			if (!cfg_base)
				continue;

			
			reg = inb(cfg_base);
			if (reg == 0xff) {
				IRDA_DEBUG(2, "%s() no chip at 0x%03x\n", __func__, cfg_base);
				continue;
			}
			
			
			outb(chip->cid_index, cfg_base);
			id = inb(cfg_base+1);
			if ((id & chip->cid_mask) == chip->cid_value) {
				IRDA_DEBUG(2, "%s() Found %s chip, revision=%d\n",
					   __func__, chip->name, id & ~chip->cid_mask);

				if (pnp_succeeded) {
					memset(&info, 0, sizeof(chipio_t));
					info.cfg_base = cfg_base;
					info.fir_base = pnp_info.fir_base;
					info.dma = pnp_info.dma;
					info.irq = pnp_info.irq;

					if (info.fir_base < 0x2000) {
						IRDA_MESSAGE("%s, chip->init\n", driver_name);
						chip->init(chip, &info);
					} else
						chip->probe(chip, &info);

					if (nsc_ircc_open(&info) >= 0)
						ret = 0;
				}

				if (ret) {
					IRDA_DEBUG(2, "%s, PnP init failed\n", driver_name);
					memset(&info, 0, sizeof(chipio_t));
					info.cfg_base = cfg_base;
					info.fir_base = io[i];
					info.dma = dma[i];
					info.irq = irq[i];

					if (io[i] < 0x2000) {
						chip->init(chip, &info);
					} else
						chip->probe(chip, &info);

					if (nsc_ircc_open(&info) >= 0)
						ret = 0;
				}
				i++;
			} else {
				IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __func__, id);
			}
		} 
	}

	if (ret) {
		platform_driver_unregister(&nsc_ircc_driver);
		pnp_unregister_driver(&nsc_ircc_pnp_driver);
		pnp_registered = 0;
	}

	return ret;
}
Esempio n. 9
0
static struct irport_cb *
irport_open(int i, unsigned int iobase, unsigned int irq)
{
	struct net_device *dev;
	struct irport_cb *self;

	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);

	/* Lock the port that we need */
	if (!request_region(iobase, IO_EXTENT, driver_name)) {
		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
			   __FUNCTION__, iobase);
		goto err_out1;
	}

	/*
	 *  Allocate new instance of the driver
	 */
	dev = alloc_irdadev(sizeof(struct irport_cb));
	if (!dev) {
		IRDA_ERROR("%s(), can't allocate memory for "
			   "irda device!\n", __FUNCTION__);
		goto err_out2;
	}

	self = dev->priv;
	spin_lock_init(&self->lock);

	/* Need to store self somewhere */
	dev_self[i] = self;
	self->priv = self;
	self->index = i;

	/* Initialize IO */
	self->io.sir_base  = iobase;
        self->io.sir_ext   = IO_EXTENT;
        self->io.irq       = irq;
        self->io.fifo_size = 16;		/* 16550A and compatible */

	/* Initialize QoS for this device */
	irda_init_max_qos_capabilies(&self->qos);
	
	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200;

	self->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&self->qos);
	
	/* Bootstrap ZeroCopy Rx */
	self->rx_buff.truesize = IRDA_SKB_MAX_MTU;
	self->rx_buff.skb = __dev_alloc_skb(self->rx_buff.truesize,
					    GFP_KERNEL);
	if (self->rx_buff.skb == NULL) {
		IRDA_ERROR("%s(), can't allocate memory for "
			   "receive buffer!\n", __FUNCTION__);
		goto err_out3;
	}
	skb_reserve(self->rx_buff.skb, 1);
	self->rx_buff.head = self->rx_buff.skb->data;
	/* No need to memset the buffer, unless you are really pedantic */

	/* Finish setup the Rx buffer descriptor */
	self->rx_buff.in_frame = FALSE;
	self->rx_buff.state = OUTSIDE_FRAME;
	self->rx_buff.data = self->rx_buff.head;

	/* Specify how much memory we want */
	self->tx_buff.truesize = 4000;
	
	/* Allocate memory if needed */
	if (self->tx_buff.truesize > 0) {
		self->tx_buff.head = kzalloc(self->tx_buff.truesize,
						      GFP_KERNEL);
		if (self->tx_buff.head == NULL) {
			IRDA_ERROR("%s(), can't allocate memory for "
				   "transmit buffer!\n", __FUNCTION__);
			goto err_out4;
		}
	}	
	self->tx_buff.data = self->tx_buff.head;

	self->netdev = dev;
	/* Keep track of module usage */
	SET_MODULE_OWNER(dev);

	/* May be overridden by piggyback drivers */
	self->interrupt    = irport_interrupt;
	self->change_speed = irport_change_speed;

	/* Override the network functions we need to use */
	dev->hard_start_xmit = irport_hard_xmit;
	dev->tx_timeout	     = irport_timeout;
	dev->watchdog_timeo  = HZ;  /* Allow time enough for speed change */
	dev->open            = irport_net_open;
	dev->stop            = irport_net_close;
	dev->get_stats	     = irport_net_get_stats;
	dev->do_ioctl        = irport_net_ioctl;

	/* Make ifconfig display some details */
	dev->base_addr = iobase;
	dev->irq = irq;

	if (register_netdev(dev)) {
		IRDA_ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
		goto err_out5;
	}
	IRDA_MESSAGE("IrDA: Registered device %s (irport io=0x%X irq=%d)\n",
		dev->name, iobase, irq);

	return self;
 err_out5:
	kfree(self->tx_buff.head);
 err_out4:
	kfree_skb(self->rx_buff.skb);
 err_out3:
	free_netdev(dev);
	dev_self[i] = NULL;
 err_out2:
	release_region(iobase, IO_EXTENT);
 err_out1:
	return NULL;
}