/*
 * Verifies if a request should be dispatched or not.
 *
 * Returns:
 *  <0 in case of error.
 *  0  if request passes the checks
 */
static int sd_check_request(struct sd_host *host, struct request *req)
{
	unsigned long nr_sectors;

	if (req->cmd_type != REQ_TYPE_FS)
		return -EIO;

	if (test_bit(__SD_MEDIA_CHANGED, &host->flags)) {
		sd_printk(KERN_ERR, "media changed, aborting\n");
		return -ENOMEDIUM;
	}

	/* unit is kernel sectors */
	nr_sectors =
	    host->card.csd.capacity << (host->card.csd.read_blkbits - KERNEL_SECTOR_SHIFT);

	/* keep our reads within limits */

	if ((blk_rq_pos(req) + blk_rq_cur_sectors(req)) > nr_sectors) {
		sd_printk(KERN_ERR, "reading past end, aborting\n");
		return -EINVAL;
	} 

	return 0;
}
static int sd_welcome_card(struct sd_host *host)
{
	int retval;

	/* soft reset the card */
	retval = sd_reset_sequence(host);
	if (retval < 0 || sd_card_is_bad(host))
		goto out;

	/* read Operating Conditions Register */
	retval = sd_read_ocr(host);
	if (retval < 0)
		goto err_bad_card;

	/* refuse to drive cards reporting voltage ranges out of scope */
	if (!(host->ocr & host->ocr_avail)) {
		sd_printk(KERN_WARNING, "reported OCR (%08x)"
			  " indicates that it is not safe to use this"
			  " card with a GameCube\n", host->ocr);
		retval = -ENODEV;
		goto err_bad_card;
	}

	/* read and decode the Card Specific Data */
	retval = sd_read_csd(host);
	if (retval < 0)
		goto err_bad_card;
	mmc_decode_csd(&host->card);

	/* calculate some card access related timeouts */
	sd_calc_timeouts(host);

	/* read and decode the Card Identification Data */
	retval = sd_read_cid(host);
	if (retval < 0)
		goto err_bad_card;
	mmc_decode_cid(&host->card);

	sd_printk(KERN_INFO, "slot%d: descr \"%s\", size %luk, block %ub,"
		  " serial %08x\n",
		  to_channel(exi_get_exi_channel(host->exi_device)),
		  host->card.cid.prod_name,
		  (unsigned long)((host->card.csd.capacity *
			  (1 << host->card.csd.read_blkbits)) / 1024),
		  1 << host->card.csd.read_blkbits,
		  host->card.cid.serial);

	retval = 0;
	goto out;

err_bad_card:
	sd_card_set_bad(host);
out:
	return retval;
}
/*
 * Initializes the block layer interfaces.
 */
static int sd_init_blk_dev(struct sd_host *host)
{
	struct gendisk *disk;
	struct request_queue *queue;
	int channel;
	int retval;

	channel = to_channel(exi_get_exi_channel(host->exi_device));

	/* queue */
	retval = -ENOMEM;
	spin_lock_init(&host->queue_lock);
	queue = blk_init_queue(sd_request_func, &host->queue_lock);
	if (!queue) {
		sd_printk(KERN_ERR, "error initializing queue\n");
		goto err_blk_init_queue;
	}
	blk_queue_dma_alignment(queue, EXI_DMA_ALIGN);
	blk_queue_max_phys_segments(queue, 1);
	blk_queue_max_hw_segments(queue, 1);
	blk_queue_max_sectors(queue, 8);
	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, queue);
	queue->queuedata = host;
	host->queue = queue;

	/* disk */
	disk = alloc_disk(1 << MMC_SHIFT);
	if (!disk) {
		sd_printk(KERN_ERR, "error allocating disk\n");
		goto err_alloc_disk;
	}
	disk->major = SD_MAJOR;
	disk->first_minor = channel << MMC_SHIFT;
	disk->fops = &sd_fops;
	sprintf(disk->disk_name, "%s%c", SD_NAME, 'a' + channel);
	disk->private_data = host;
	disk->queue = host->queue;
	host->disk = disk;

	retval = 0;
	goto out;

err_alloc_disk:
	blk_cleanup_queue(host->queue);
	host->queue = NULL;
err_blk_init_queue:
out:
	return retval;
}
Exemple #4
0
/*
 * ubicom32sd_mmc_get_cd
 */
static int ubicom32sd_mmc_get_cd(struct mmc_host *mmc)
{
	struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
	sd_printk("%s: get cd %u %u\n", mmc_hostname(mmc), ud->pdata->cards[0].pin_cd, gpio_get_value(ud->pdata->cards[0].pin_cd));

	return gpio_get_value(ud->pdata->cards[0].pin_cd) ?
				ud->pdata->cards[0].cd_polarity :
				!ud->pdata->cards[0].cd_polarity;
}
static int __init sd_init_module(void)
{
	int retval = 0;

	sd_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION,
		  sd_driver_version);

	if (register_blkdev(SD_MAJOR, DRV_MODULE_NAME)) {
		sd_printk(KERN_ERR, "unable to register major %d\n", SD_MAJOR);
		retval = -EIO;
		goto out;
	}

	retval = exi_driver_register(&sd_driver);

out:
	return retval;
}
Exemple #6
0
/*
 * ubicom32sd_mmc_set_ios
 */
static void ubicom32sd_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
	u32_t command = SDTIO_COMMAND_SETUP << SDTIO_COMMAND_SHIFT;
	u32_t arg = 0;
	sd_printk("%s: ios call bw:%u pm:%u clk:%u\n", mmc_hostname(mmc), 1 << ios->bus_width, ios->power_mode, ios->clock);

	switch (ios->bus_width) {
	case MMC_BUS_WIDTH_1:
		command |= SDTIO_COMMAND_FLAG_SET_WIDTH | SDTIO_COMMAND_FLAG_1BIT;
		break;

	case MMC_BUS_WIDTH_4:
		command |= SDTIO_COMMAND_FLAG_SET_WIDTH | SDTIO_COMMAND_FLAG_4BIT;
		break;
	}

	if (ios->clock) {
		arg = ios->clock;
		command |= SDTIO_COMMAND_FLAG_SET_CLOCK;
	}

	switch (ios->power_mode) {

	/*
	 * Turn off the SD bus (power + clock)
	 */
	case MMC_POWER_OFF:
		gpio_set_value(ud->pdata->cards[0].pin_pwr, !ud->pdata->cards[0].pwr_polarity);
		command |= SDTIO_COMMAND_FLAG_SET_CLOCK;
		break;

	/*
	 * Turn on the power to the SD bus
	 */
	case MMC_POWER_ON:
		gpio_set_value(ud->pdata->cards[0].pin_pwr, ud->pdata->cards[0].pwr_polarity);
		break;

	/*
	 * Turn on the clock to the SD bus
	 */
	case MMC_POWER_UP:
		/*
		 * Done above
		 */
		break;
	}

	ubicom32sd_send_command_sync(ud, command, arg);

	/*
	 * Let the power settle down
	 */
	udelay(500);
}
/*
 * Configure exchange of protection information between OS and HBA.
 */
void sd_dif_config_host(struct scsi_disk *sdkp)
{
	struct scsi_device *sdp = sdkp->device;
	struct gendisk *disk = sdkp->disk;
	u8 type = sdkp->protection_type;
	int dif, dix;

	dif = scsi_host_dif_capable(sdp->host, type);
	dix = scsi_host_dix_capable(sdp->host, type);

	if (!dix && scsi_host_dix_capable(sdp->host, 0)) {
		dif = 0; dix = 1;
	}

	if (!dix)
		return;

	/* Enable DMA of protection information */
	if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP)
		if (type == SD_DIF_TYPE3_PROTECTION)
			blk_integrity_register(disk, &dif_type3_integrity_ip);
		else
			blk_integrity_register(disk, &dif_type1_integrity_ip);
	else
		if (type == SD_DIF_TYPE3_PROTECTION)
			blk_integrity_register(disk, &dif_type3_integrity_crc);
		else
			blk_integrity_register(disk, &dif_type1_integrity_crc);

	sd_printk(KERN_NOTICE, sdkp,
		  "Enabling DIX %s protection\n", disk->integrity->name);

	/* Signal to block layer that we support sector tagging */
	if (dif && type && sdkp->ATO) {
		if (type == SD_DIF_TYPE3_PROTECTION)
			disk->integrity->tag_size = sizeof(u16) + sizeof(u32);
		else
			disk->integrity->tag_size = sizeof(u16);

		sd_printk(KERN_NOTICE, sdkp, "DIF application tag size %u\n",
			  disk->integrity->tag_size);
	}
}
Exemple #8
0
/*
 * ubicom32sd_mmc_get_ro
 */
static int ubicom32sd_mmc_get_ro(struct mmc_host *mmc)
{
	struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
	if (ud->pdata->cards[0].pin_wp == -1) {
		return ud->pdata->cards[0].wp_polarity;
	}

	sd_printk("%s: get ro %u %u\n", mmc_hostname(mmc), ud->pdata->cards[0].pin_wp, gpio_get_value(ud->pdata->cards[0].pin_wp));
	return gpio_get_value(ud->pdata->cards[0].pin_wp) ? 
				ud->pdata->cards[0].wp_polarity :
				!ud->pdata->cards[0].wp_polarity;
}
Exemple #9
0
/**
 * Issue a REPORT ZONES scsi command.
 */
static int sd_zbc_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
			       unsigned int buflen, sector_t lba)
{
	struct scsi_device *sdp = sdkp->device;
	const int timeout = sdp->request_queue->rq_timeout;
	struct scsi_sense_hdr sshdr;
	unsigned char cmd[16];
	unsigned int rep_len;
	int result;

	memset(cmd, 0, 16);
	cmd[0] = ZBC_IN;
	cmd[1] = ZI_REPORT_ZONES;
	put_unaligned_be64(lba, &cmd[2]);
	put_unaligned_be32(buflen, &cmd[10]);
	memset(buf, 0, buflen);

	result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
				  buf, buflen, &sshdr,
				  timeout, SD_MAX_RETRIES, NULL);
	if (result) {
		sd_printk(KERN_ERR, sdkp,
			  "REPORT ZONES lba %llu failed with %d/%d\n",
			  (unsigned long long)lba,
			  host_byte(result), driver_byte(result));
		return -EIO;
	}

	rep_len = get_unaligned_be32(&buf[0]);
	if (rep_len < 64) {
		sd_printk(KERN_ERR, sdkp,
			  "REPORT ZONES report invalid length %u\n",
			  rep_len);
		return -EIO;
	}

	return 0;
}
/*
 * Terminates a host.
 */
static void sd_kill(struct sd_host *host)
{
	if (host->refcnt > 0) {
		sd_printk(KERN_ERR, "hey! card removed while in use!\n");
		set_bit(__SD_MEDIA_CHANGED, &host->flags);
	}

	sd_exit(host);
	host->exi_device = NULL;

	/* release the host immediately when not in use */
	if (!host->refcnt)
		kfree(host);
}
static void sd_print_cid(struct mmc_cid *cid)
{
	sd_printk(KERN_INFO,
		  "manfid = %d\n"
		  "oemid = %d\n"
		  "prod_name = %s\n"
		  "hwrev = %d\n"
		  "fwrev = %d\n"
		  "serial = %08x\n"
		  "year = %d\n"
		  "month = %d\n",
		  cid->manfid,
		  cid->oemid,
		  cid->prod_name,
		  cid->hwrev, cid->fwrev, cid->serial, cid->year, cid->month);
}
/*
 * Initializes and launches the IO thread.
 */
static int sd_init_io_thread(struct sd_host *host)
{
	int channel;
	int result = 0;

	channel = to_channel(exi_get_exi_channel(host->exi_device));

	mutex_init(&host->io_mutex);
	host->io_thread = kthread_run(sd_io_thread, host,
				      "ksdiod/%c", 'a' + channel);
	if (IS_ERR(host->io_thread)) {
		sd_printk(KERN_ERR, "error creating io thread\n");
		result = PTR_ERR(host->io_thread);
	}
	return result;
}
/*
 * Given a 128-bit response, decode to our card CSD structure.
 */
static void mmc_decode_csd(struct mmc_card *card)
{
	struct mmc_csd *csd = &card->csd;
	unsigned int e, m, csd_struct;
	u32 *resp = card->raw_csd;

	/*
	 * We only understand CSD structure v1.0, v1.1 and v2.
	 * v2 has extra information in bits 15, 11 and 10.
	 */
	csd_struct = UNSTUFF_BITS(resp, 126, 2);
	if (csd_struct != 0 && csd_struct != 1 && csd_struct != 2) {
		sd_printk(KERN_ERR, "unrecognised CSD structure"
			  " version %d\n", csd_struct);
		return;
	}

	csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4);

	/* TAAC */
	m = UNSTUFF_BITS(resp, 115, 4);
	e = UNSTUFF_BITS(resp, 112, 3);
	csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;

	/* NSAC */
	csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100;

	/* TRAN_SPEED */
	m = UNSTUFF_BITS(resp, 99, 4);
	e = UNSTUFF_BITS(resp, 96, 3);
	csd->max_dtr = tran_exp[e] * tran_mant[m];

	/* CCC */
	csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);

	/* READ_BL_LEN */
	csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);

	/* C_SIZE */
	m = UNSTUFF_BITS(resp, 62, 12);

	/* C_SIZE_MULT */
	e = UNSTUFF_BITS(resp, 47, 3);

	csd->capacity = (1 + m) << (e + 2);	/* in card blocks */
}
Exemple #14
0
/*
 * ubicom32sd_interrupt
 */
static irqreturn_t ubicom32sd_interrupt(int irq, void *dev)
{
	struct mmc_host *mmc = (struct mmc_host *)dev;
	struct mmc_request *mrq;
	struct ubicom32sd_data *ud;
	u32_t int_status;

	if (!mmc) {
		return IRQ_HANDLED;
	}

	ud = (struct ubicom32sd_data *)mmc_priv(mmc);
	if (!ud) {
		return IRQ_HANDLED;
	}

	int_status = ud->regs->int_status;
	ud->regs->int_status &= ~int_status;

	if (int_status & SDTIO_VP_INT_STATUS_SDIO_INT) {
		if (ud->int_en) {
			ud->int_pend = 0;
			mmc_signal_sdio_irq(mmc);
		} else {
			ud->int_pend++;
		}
	}

	if (!(int_status & SDTIO_VP_INT_STATUS_DONE)) {
		return IRQ_HANDLED;
	}

	mrq = ud->mrq;
	if (!mrq) {
		sd_printk("%s: Spurious interrupt", mmc_hostname(mmc));
		return IRQ_HANDLED;
	}
	ud->mrq = NULL;

	/*
	 * SDTIO_VP_INT_DONE
	 */
	if (mrq->cmd->flags & MMC_RSP_PRESENT) {
		struct mmc_command *cmd = mrq->cmd;
		cmd->error = 0;

		if ((cmd->flags & MMC_RSP_CRC) && (int_status & SDTIO_VP_INT_STATUS_CMD_RSP_CRC)) {
			cmd->error = -EILSEQ;
			sd_printk("%s:\t\t\tRSP CRC Error\n", mmc_hostname(mmc));
		} else if (int_status & SDTIO_VP_INT_STATUS_CMD_RSP_TIMEOUT) {
			cmd->error = -ETIMEDOUT;
			sd_printk("%s:\t\t\tRSP Timeout\n", mmc_hostname(mmc));
			goto done;
		} else if (cmd->flags & MMC_RSP_136) {
			cmd->resp[0] = ud->regs->cmd_rsp0;
			cmd->resp[1] = ud->regs->cmd_rsp1;
			cmd->resp[2] = ud->regs->cmd_rsp2;
			cmd->resp[3] = ud->regs->cmd_rsp3;
		} else {
			cmd->resp[0] = ud->regs->cmd_rsp0;
		}
		sd_printk("%s:\t\t\tResponse %08x %08x %08x %08x err=%d\n", mmc_hostname(mmc), cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], cmd->error);
	}

	if (mrq->data) {
		struct mmc_data *data = mrq->data;

		if (int_status & SDTIO_VP_INT_STATUS_DATA_TIMEOUT) {
			data->error = -ETIMEDOUT;
			sd_printk("%s:\t\t\tData Timeout\n", mmc_hostname(mmc));
			goto done;
		} else if (int_status & SDTIO_VP_INT_STATUS_DATA_CRC_ERR) {
			data->error = -EILSEQ;
			sd_printk("%s:\t\t\tData CRC\n", mmc_hostname(mmc));
			goto done;
		} else if (int_status & SDTIO_VP_INT_STATUS_DATA_PROG_ERR) {
			data->error = -EILSEQ;
			sd_printk("%s:\t\t\tData Program Error\n", mmc_hostname(mmc));
			goto done;
		} else {
			data->error = 0;
			data->bytes_xfered = ud->regs->data_bytes_transferred;
		}
	}

	if (mrq->stop && (mrq->stop->flags & MMC_RSP_PRESENT)) {
		struct mmc_command *stop = mrq->stop;
		stop->error = 0;

		if ((stop->flags & MMC_RSP_CRC) && (int_status & SDTIO_VP_INT_STATUS_STOP_RSP_CRC)) {
			stop->error = -EILSEQ;
			sd_printk("%s:\t\t\tStop RSP CRC Error\n", mmc_hostname(mmc));
		} else if (int_status & SDTIO_VP_INT_STATUS_STOP_RSP_TIMEOUT) {
			stop->error = -ETIMEDOUT;
			sd_printk("%s:\t\t\tStop RSP Timeout\n", mmc_hostname(mmc));
			goto done;
		} else if (stop->flags & MMC_RSP_136) {
			stop->resp[0] = ud->regs->stop_rsp0;
			stop->resp[1] = ud->regs->stop_rsp1;
			stop->resp[2] = ud->regs->stop_rsp2;
			stop->resp[3] = ud->regs->stop_rsp3;
		} else {
			stop->resp[0] = ud->regs->stop_rsp0;
		}
		sd_printk("%s:\t\t\tStop Response %08x %08x %08x %08x err=%d\n", mmc_hostname(mmc), stop->resp[0], stop->resp[1], stop->resp[2], stop->resp[3], stop->error);
	}

done:
	mmc_request_done(mmc, mrq);

	return IRQ_HANDLED;
}
Exemple #15
0
/*
 * ubicom32sd_mmc_request
 */
static void ubicom32sd_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct ubicom32sd_data *ud = (struct ubicom32sd_data *)mmc_priv(mmc);
	u32_t command = SDTIO_COMMAND_EXECUTE << SDTIO_COMMAND_SHIFT;
	int ret = 0;

	WARN(ud->mrq != NULL, "ud->mrq still set to %p\n", ud->mrq);
	//pr_debug("send cmd %08x arg %08x flags %08x\n", cmd->opcode, cmd->arg, cmd->flags);

	if (mrq->cmd) {
		struct mmc_command *cmd = mrq->cmd;

		sd_printk("%s:\t\t\tsetup cmd %02d arg %08x flags %08x\n", mmc_hostname(mmc), cmd->opcode, cmd->arg, cmd->flags);

		ud->regs->cmd_opcode = cmd->opcode;
		ud->regs->cmd_arg = cmd->arg;

		command |= SDTIO_COMMAND_FLAG_CMD;

		if (cmd->flags & MMC_RSP_PRESENT) {
			command |= SDTIO_COMMAND_FLAG_CMD_RSP;
		}

		if (cmd->flags & MMC_RSP_136) {
			command |= SDTIO_COMMAND_FLAG_CMD_RSP_136;
		}

		if (cmd->flags & MMC_RSP_CRC) {
			command |= SDTIO_COMMAND_FLAG_CMD_RSP_CRC;
		}
	}

	if (mrq->data) {
		struct mmc_data *data = mrq->data;
		struct scatterlist *sg = data->sg;
		int i;

		sd_printk("%s:\t\t\tsetup data blksz %d num %d sglen=%d fl=%08x Tns=%u\n",
			  mmc_hostname(mmc), data->blksz, data->blocks, data->sg_len,
			  data->flags, data->timeout_ns);

		if (data->sg_len > SDTIO_MAX_SG_BLOCKS) {
			ret = -EINVAL;
			data->error = -EINVAL;
			goto fail;
		}

		ud->regs->data_timeout_ns = data->timeout_ns;
		ud->regs->data_blksz = data->blksz;
		ud->regs->data_blkct = data->blocks;
		ud->regs->sg_len = data->sg_len;

		/*
		 * Load all of our sg list into the driver sg buffer
		 */
		for (i = 0; i < data->sg_len; i++) {
			sd_printk("%s: sg %d = %p %d\n", mmc_hostname(mmc), i, sg_virt(sg), sg->length);
			ud->regs->sg[i].addr = sg_virt(sg);
			ud->regs->sg[i].len = sg->length;
			if (((u32_t)ud->regs->sg[i].addr & 0x03) || (sg->length & 0x03)) {
				sd_printk("%s: Need aligned buffers\n", mmc_hostname(mmc));
				ret = -EINVAL;
				data->error = -EINVAL;
				goto fail;
			}
			sg++;
		}
		if (data->flags & MMC_DATA_READ) {
			command |= SDTIO_COMMAND_FLAG_DATA_RD;
		} else if (data->flags & MMC_DATA_WRITE) {
			command |= SDTIO_COMMAND_FLAG_DATA_WR;
		} else if (data->flags & MMC_DATA_STREAM) {
			command |= SDTIO_COMMAND_FLAG_DATA_STREAM;
		}
	}

	if (mrq->stop) {
		struct mmc_command *stop = mrq->stop;
		sd_printk("%s: \t\t\tsetup stop %02d arg %08x flags %08x\n", mmc_hostname(mmc), stop->opcode, stop->arg, stop->flags);

		ud->regs->stop_opcode = stop->opcode;
		ud->regs->stop_arg = stop->arg;

		command |= SDTIO_COMMAND_FLAG_STOP_CMD;

		if (stop->flags & MMC_RSP_PRESENT) {
			command |= SDTIO_COMMAND_FLAG_STOP_RSP;
		}

		if (stop->flags & MMC_RSP_136) {
			command |= SDTIO_COMMAND_FLAG_STOP_RSP_136;
		}

		if (stop->flags & MMC_RSP_CRC) {
			command |= SDTIO_COMMAND_FLAG_STOP_RSP_CRC;
		}
	}

	ud->mrq = mrq;

	sd_printk("%s: Sending command %08x\n", mmc_hostname(mmc), command);

	ubicom32sd_send_command(ud, command, 0);

	return;
fail:
	sd_printk("%s: mmcreq ret = %d\n", mmc_hostname(mmc), ret);
	mrq->cmd->error = ret;
	mmc_request_done(mmc, mrq);
}
/*
 * Given the decoded CSD structure, decode the raw CID to our CID structure.
 */
static void mmc_decode_cid(struct mmc_card *card)
{
	u32 *resp = card->raw_cid;

	memset(&card->cid, 0, sizeof(struct mmc_cid));

	if (mmc_card_sd(card)) {
		card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
		card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
		card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
		card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
		card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
		card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
		card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
		card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4);
		card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4);
		card->cid.serial = UNSTUFF_BITS(resp, 24, 32);
		card->cid.year = UNSTUFF_BITS(resp, 12, 8);
		card->cid.month = UNSTUFF_BITS(resp, 8, 4);
		card->cid.year += 2000;
	} else {
		/*
		 * The selection of the format here is guesswork based upon
		 * information people have sent to date.
		 */
		switch (card->csd.mmca_vsn) {
		case 0:	/* MMC v1.0 - v1.2 */
		case 1:	/* MMC v1.4 */
			card->cid.manfid = UNSTUFF_BITS(resp, 104, 24);
			card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
			card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
			card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
			card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
			card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
			card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
			card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8);
			card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4);
			card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4);
			card->cid.serial = UNSTUFF_BITS(resp, 16, 24);
			card->cid.month = UNSTUFF_BITS(resp, 12, 4);
			card->cid.year = UNSTUFF_BITS(resp, 8, 4);
			card->cid.year += 1997;
			break;
		case 2:	/* MMC v2.0 - v2.2 */
		case 3:	/* MMC v3.1 - v3.3 */
			card->cid.manfid = UNSTUFF_BITS(resp, 120, 8);
			card->cid.oemid = UNSTUFF_BITS(resp, 104, 16);
			card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8);
			card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8);
			card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8);
			card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8);
			card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8);
			card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8);
			card->cid.serial = UNSTUFF_BITS(resp, 16, 32);
			card->cid.month = UNSTUFF_BITS(resp, 12, 4);
			card->cid.year = UNSTUFF_BITS(resp, 8, 4);
			card->cid.year += 1997;
			break;
		default:
			sd_printk(KERN_ERR, "card has unknown MMCA"
				  " version %d\n", card->csd.mmca_vsn);
			break;
		}
	}
}