static struct card_blk_data *card_blk_alloc(struct memory_card *card)
{
	struct card_blk_data *card_data;
	int devidx, ret;

	devidx = find_first_zero_bit(dev_use, CARD_NUM_MINORS);

	if(card->card_type == CARD_INAND)
		devidx = CARD_INAND_START_MINOR>>CARD_SHIFT;
	
	if (devidx >= CARD_NUM_MINORS)
		return ERR_PTR(-ENOSPC);
	__set_bit(devidx, dev_use);

	card_data = kmalloc(sizeof(struct card_blk_data), GFP_KERNEL);
	if (!card_data) {
		ret = -ENOMEM;
		return ERR_PTR(ret);
	}

	memset(card_data, 0, sizeof(struct card_blk_data));

	card_data->block_bits = 9;

	card_data->disk = alloc_disk(1 << CARD_SHIFT);
	if (card_data->disk == NULL) {
		ret = -ENOMEM;
		kfree(card_data);
		return ERR_PTR(ret);
	}

	spin_lock_init(&card_data->lock);
	card_data->usage = 1;

	ret = card_init_queue(&card_data->queue, card, &card_data->lock);
	if (ret) {
		put_disk(card_data->disk);
		return ERR_PTR(ret);
	}

	card_data->queue.prep_fn = card_blk_prep_rq;
	card_data->queue.issue_fn = card_blk_issue_rq;
	card_data->queue.data = card_data;

	card_data->disk->major = major;
	card_data->disk->minors = 1 << CARD_SHIFT;
	card_data->disk->first_minor = devidx << CARD_SHIFT;
	card_data->disk->fops = &card_ops;
	card_data->disk->private_data = card_data;
	card_data->disk->queue = card_data->queue.queue;
	card_data->disk->driverfs_dev = &card->dev;

	sprintf(card_data->disk->disk_name, "cardblk%s", card->name);

	blk_queue_logical_block_size(card_data->queue.queue, 1 << card_data->block_bits);

	set_capacity(card_data->disk, card->capacity);

	return card_data;
}
示例#2
0
/**
 * add_last_partition : add card last partition as a full device, refer to
 * board-****.c  inand_partition_info[] last partition
 * @card: inand_card_lp
 * @size: set last partition capacity
 */
int add_last_partition(struct memory_card* card, uint64_t offset ,uint64_t size)
{
      struct card_blk_data *card_data;
      int ret;

      card_data = kmalloc(sizeof(struct card_blk_data), GFP_KERNEL);
      if (!card_data) {
            ret = -ENOMEM;
            return ret;
      }

      memset(card_data, 0, sizeof(struct card_blk_data));

      if(card->state & CARD_STATE_READONLY)
            card_data->read_only = 1;

      card_data->block_bits = 9;

      card_data->disk = alloc_disk(1 << CARD_SHIFT);
      if (card_data->disk == NULL) {
            ret = -ENOMEM;
            kfree(card_data);
            return ret;
      }

      spin_lock_init(&card_data->lock);
      card_data->usage = 1;

      ret = card_init_queue(&card_data->queue, card, &card_data->lock);
      if (ret) {
            put_disk(card_data->disk);
            return ret;
      }

      card->part_offset=offset;
      card_data->queue.prep_fn = card_blk_prep_rq;
      card_data->queue.issue_fn = card_blk_issue_rq;
      card_data->queue.data = card_data;

      card_data->disk->major = INAND_LAST_PART_MAJOR;
      card_data->disk->minors = 1 << CARD_SHIFT;
      card_data->disk->first_minor = 0;
      card_data->disk->fops = &card_ops;
      card_data->disk->private_data = card_data;
      card_data->disk->queue = card_data->queue.queue;
      card_data->disk->driverfs_dev = &card->dev;

      sprintf(card_data->disk->disk_name, "cardblk%s", card->name);

      blk_queue_logical_block_size(card_data->queue.queue, 1 << card_data->block_bits);

      set_capacity(card_data->disk, size);
      card_set_drvdata(card, card_data);
      add_disk(card_data->disk);
      return 0;
}