static int brcmf_ops_sdio_probe(struct sdio_func *func,
			      const struct sdio_device_id *id)
{
	int ret = 0;
	struct brcmf_sdio_dev *sdiodev;
	brcmf_dbg(TRACE, "Enter\n");
	brcmf_dbg(TRACE, "func->class=%x\n", func->class);
	brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
	brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
	brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);

	if (func->num == 1) {
		if (dev_get_drvdata(&func->card->dev)) {
			brcmf_dbg(ERROR, "card private drvdata occupied\n");
			return -ENXIO;
		}
		sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
		if (!sdiodev)
			return -ENOMEM;
		sdiodev->func[0] = func->card->sdio_func[0];
		sdiodev->func[1] = func;
		dev_set_drvdata(&func->card->dev, sdiodev);

		atomic_set(&sdiodev->suspend, false);
		init_waitqueue_head(&sdiodev->request_byte_wait);
		init_waitqueue_head(&sdiodev->request_word_wait);
		init_waitqueue_head(&sdiodev->request_packet_wait);
		init_waitqueue_head(&sdiodev->request_buffer_wait);
	}

	if (func->num == 2) {
		sdiodev = dev_get_drvdata(&func->card->dev);
		if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
			return -ENODEV;
		sdiodev->func[2] = func;

		brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
		ret = brcmf_sdio_probe(sdiodev);
	}

	return ret;
}
static int brcmf_ops_sdio_probe(struct sdio_func *func,
				const struct sdio_device_id *id)
{
	int err;
	struct brcmf_sdio_dev *sdiodev;
	struct brcmf_bus *bus_if;
	struct mmc_host *host;
	uint max_blocks;

	brcmf_dbg(SDIO, "Enter\n");
	brcmf_dbg(SDIO, "Class=%x\n", func->class);
	brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor);
	brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
	brcmf_dbg(SDIO, "Function#: %d\n", func->num);

	/* Consume func num 1 but dont do anything with it. */
	if (func->num == 1)
		return 0;

	/* Ignore anything but func 2 */
	if (func->num != 2)
		return -ENODEV;

	bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
	if (!bus_if)
		return -ENOMEM;
	sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
	if (!sdiodev) {
		kfree(bus_if);
		return -ENOMEM;
	}

	sdiodev->func[0] = func->card->sdio_func[0];
	sdiodev->func[1] = func->card->sdio_func[0];
	sdiodev->func[2] = func;

	sdiodev->bus_if = bus_if;
	bus_if->bus_priv.sdio = sdiodev;
	dev_set_drvdata(&func->dev, bus_if);
	dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
	sdiodev->dev = &sdiodev->func[1]->dev;
	sdiodev->pdata = brcmfmac_sdio_pdata;

	atomic_set(&sdiodev->suspend, false);
	init_waitqueue_head(&sdiodev->request_byte_wait);
	init_waitqueue_head(&sdiodev->request_word_wait);
	init_waitqueue_head(&sdiodev->request_buffer_wait);

	brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n");
	err = brcmf_sdio_probe(sdiodev);
	if (err) {
		brcmf_err("F2 error, probe failed %d...\n", err);
		goto fail;
	}

	/*
	 * determine host related variables after brcmf_sdio_probe()
	 * as func->cur_blksize is properly set and F2 init has been
	 * completed successfully.
	 */
	host = func->card->host;
	sdiodev->sg_support = host->max_segs > 1;
	max_blocks = min_t(uint, host->max_blk_count, 511u);
	sdiodev->max_request_size = min_t(uint, host->max_req_size,
					  max_blocks * func->cur_blksize);
	sdiodev->max_segment_count = min_t(uint, host->max_segs,
					   SG_MAX_SINGLE_ALLOC);
	sdiodev->max_segment_size = host->max_seg_size;
	brcmf_dbg(SDIO, "F2 init completed...\n");
	return 0;

fail:
	dev_set_drvdata(&func->dev, NULL);
	dev_set_drvdata(&sdiodev->func[1]->dev, NULL);
	kfree(sdiodev);
	kfree(bus_if);
	return err;
}