if (!count) { kfree(host_set); return 0; } 
if (!count) goto err_free_ret; 
int ata_device_add(const struct ata_probe_ent *ent){	unsigned int count = 0, i;	struct device *dev = ent->dev;	struct ata_host_set *host_set;	DPRINTK("ENTER\n");	/* alloc a container for our list of ATA ports (buses) */	host_set = kmalloc(sizeof(struct ata_host_set) +			   (ent->n_ports * sizeof(void *)), GFP_KERNEL);	if (!host_set)		return 0;	memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));	spin_lock_init(&host_set->lock);	host_set->dev = dev;	host_set->n_ports = ent->n_ports;	host_set->irq = ent->irq;	host_set->mmio_base = ent->mmio_base;	host_set->private_data = ent->private_data;	host_set->ops = ent->port_ops;	/* register each port bound to this device */	for (i = 0; i < ent->n_ports; i++) {		struct ata_port *ap;		unsigned long xfer_mode_mask;		ap = ata_host_add(ent, host_set, i);		if (!ap)			goto err_out;		host_set->ports[i] = ap;		xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |				(ap->mwdma_mask << ATA_SHIFT_MWDMA) |				(ap->pio_mask << ATA_SHIFT_PIO);		/* print per-port info to dmesg */		printk(KERN_INFO "ata%u: %cATA max %s cmd 0x%lX ctl 0x%lX "				 "bmdma 0x%lX irq %lu\n",			ap->id,			ap->flags & ATA_FLAG_SATA ? 'S' : 'P',			ata_mode_string(xfer_mode_mask),	       		ap->ioaddr.cmd_addr,	       		ap->ioaddr.ctl_addr,	       		ap->ioaddr.bmdma_addr,	       		ent->irq);		ata_chk_status(ap);		host_set->ops->irq_clear(ap);		count++;	}	if (!count) {		kfree(host_set);		return 0;	}	/* obtain irq, that is shared between channels */	if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,			DRV_NAME, host_set))		goto err_out;	/* perform each probe synchronously */	DPRINTK("probe begin\n");	for (i = 0; i < count; i++) {		struct ata_port *ap;		int rc;		ap = host_set->ports[i];		DPRINTK("ata%u: probe begin\n", ap->id);		rc = ata_bus_probe(ap);		DPRINTK("ata%u: probe end\n", ap->id);		if (rc) {			/* FIXME: do something useful here?			 * Current libata behavior will			 * tear down everything when			 * the module is removed			 * or the h/w is unplugged.			 */		}		rc = scsi_add_host(ap->host, dev);		if (rc) {			printk(KERN_ERR "ata%u: scsi_add_host failed\n",			       ap->id);			/* FIXME: do something useful here */			/* FIXME: handle unconditional calls to			 * scsi_scan_host and ata_host_remove, below,			 * at the very least			 */		}	}	/* probes are done, now scan each port's disk(s) */	DPRINTK("probe begin\n");	for (i = 0; i < count; i++) {		struct ata_port *ap = host_set->ports[i];		ata_scsi_scan_host(ap);	}	dev_set_drvdata(dev, host_set);	VPRINTK("EXIT, returning %u\n", ent->n_ports);	return ent->n_ports; /* success */err_out:	for (i = 0; i < count; i++) {		ata_host_remove(host_set->ports[i], 1);		scsi_host_put(host_set->ports[i]->host);	}	kfree(host_set);	VPRINTK("EXIT, returning 0\n");	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/57f3bda88a5e5a2810016820a932cb82931dcb1c/libata-core.c/buggy/drivers/scsi/libata-core.c