Esempio n. 1
0
static void * mmc_cim_get_status( struct mmc_dev *dev, int first )
{
	struct mmc_slot *slot = dev->slot + dev->io_request->id;
	struct mmc_response_r1 r1;
	int retval = MMC_NO_ERROR;

	DEBUG(2," first=%d\n",first);

	if ( first ) {
		mmc_simple_cmd(dev, MMC_SEND_STATUS, slot->rca, RESPONSE_R1 );
		return NULL;
	}

	switch (dev->request.cmd) {
	case MMC_SEND_STATUS:
		retval = mmc_unpack_r1(&dev->request,&r1,slot->state);
		if ( !retval || retval == MMC_ERROR_STATE_MISMATCH ) {
			slot->state = R1_CURRENT_STATE(r1.status);
			return mmc_cim_read_write_block;
		}
		break;

	default:
		break;
	}

	DEBUG(0, ": failure during cmd %d, error=%d (%s)\n", dev->request.cmd,
	      retval, mmc_result_to_string(retval));
	mmc_finish_io_request(dev,0);
	return mmc_cim_default_state;
}
Esempio n. 2
0
static void * mmc_cim_single_card_acq( struct mmc_dev *dev, int first )
{
	struct mmc_response_r3 r3;
	struct mmc_response_r1 r1;
	struct mmc_slot *slot = dev->slot;     /* Must be slot 0 */
	int retval;

	DEBUG(2,"\n");

	if ( first ) {
		mmc_simple_cmd(dev, MMC_GO_IDLE_STATE, 0, RESPONSE_NONE);
                slot->sd = 0; 
		return NULL;
	}

	switch (dev->request.cmd) {
	case MMC_GO_IDLE_STATE: /* No response to parse */
		if ( (dev->sdrive->flags & MMC_SDFLAG_VOLTAGE ))
			DEBUG(0,": error - current driver doesn't do OCR\n");
		mmc_simple_cmd(dev, MMC_APP_CMD,  0, RESPONSE_R1);
		break;

        case MMC_APP_CMD:
        	retval = mmc_unpack_r1(&dev->request,&r1,slot->state);
		if ( retval ) {
			DEBUG(0, ": unable to MMC_APP_CMD error=%d (%s)\n", 
			      retval, mmc_result_to_string(retval));
			mmc_simple_cmd(dev, MMC_SEND_OP_COND, dev->sdrive->ocr, RESPONSE_R3);
		}
                else { 
	            mmc_simple_cmd(dev, SD_SEND_OP_COND, 0x00ff8000, RESPONSE_R3);
                }
		break;

        case SD_SEND_OP_COND:
                retval = mmc_unpack_r3(&dev->request, &r3);
                if ( retval ) {

                  /* Try MMC card */
                    mmc_simple_cmd(dev, MMC_SEND_OP_COND, dev->sdrive->ocr, RESPONSE_R3);
                    break;
		}

                DEBUG(2,": read ocr value = 0x%08x\n", r3.ocr);

		if (!(r3.ocr & MMC_CARD_BUSY)) {
			mmc_simple_cmd(dev, MMC_APP_CMD, 0, RESPONSE_R1);
		}
		else {

		  /* Set the data bus width to 4 bits */
                  slot->sd = 1; /* SD Card ready */
                  slot->state = CARD_STATE_READY;
		  mmc_simple_cmd(dev, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID);

		}
		break;

	case MMC_SEND_OP_COND:
		retval = mmc_unpack_r3(&dev->request, &r3);
		if ( retval ) {
			DEBUG(0,": failed SEND_OP_COND error=%d (%s)\n", 
			      retval, mmc_result_to_string(retval));
			return mmc_cim_default_state;
		}

		DEBUG(2,": read ocr value = 0x%08x\n", r3.ocr);
		if (!(r3.ocr & MMC_CARD_BUSY)) {
	                mmc_simple_cmd(dev, MMC_SEND_OP_COND, dev->sdrive->ocr, RESPONSE_R3);
		}
		else {
		        slot->sd = 0; /* MMC Card ready */
			slot->state = CARD_STATE_READY;
			mmc_simple_cmd(dev, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID);
		}
		break;
		
	case MMC_ALL_SEND_CID: 
		retval = mmc_unpack_cid( &dev->request, &slot->cid );
		if ( retval ) {
			DEBUG(0,": unable to ALL_SEND_CID error=%d (%s)\n", 
			      retval, mmc_result_to_string(retval));
			return mmc_cim_default_state;
		}
		slot->state = CARD_STATE_IDENT;
		if(slot->sd)
		{
                   mmc_simple_cmd(dev, MMC_SET_RELATIVE_ADDR, 0, RESPONSE_R6);
                }
                else
		{
		   mmc_simple_cmd(dev, MMC_SET_RELATIVE_ADDR, ID_TO_RCA(slot->id) << 16, RESPONSE_R1);
                } 
		break;

        case MMC_SET_RELATIVE_ADDR:
	        if (slot->sd)
		{
		  retval = mmc_unpack_r6(&dev->request, &r1, slot->state, &slot->rca);
                  slot->rca = slot->rca << 16; 
                  DEBUG(2, ": Get RCA from SD: 0x%04x Status: %x\n", slot->rca, r1.status);
                }
                else
		{
		  retval = mmc_unpack_r1(&dev->request,&r1,slot->state);
		  slot->rca = ID_TO_RCA(slot->id) << 16;
	        }
		if ( retval ) {
			DEBUG(0, ": unable to SET_RELATIVE_ADDR error=%d (%s)\n", 
			      retval, mmc_result_to_string(retval));
			return mmc_cim_default_state;
		}

		slot->state = CARD_STATE_STBY;
                mmc_simple_cmd(dev, MMC_SEND_CSD, slot->rca, RESPONSE_R2_CSD);
             
		break;
        
	case MMC_SEND_CSD:
		retval = mmc_unpack_csd(&dev->request, &slot->csd);
		if ( retval ) {
			DEBUG(0, ": unable to SEND_CSD error=%d (%s)\n", 
			      retval, mmc_result_to_string(retval));
			return mmc_cim_default_state;
		}
		if ( slot->csd.dsr_imp ) {
			DEBUG(0, ": driver doesn't support setting DSR\n");
				// mmc_simple_cmd(dev, MMC_SET_DSR, 0, RESPONSE_NONE);
		}
		mmc_configure_card( dev, 0 );
		return mmc_cim_default_state;

	default:
		DEBUG(0, ": error!  Illegal last cmd %d\n", dev->request.cmd);
		return mmc_cim_default_state;
	}
	return NULL;
}
Esempio n. 3
0
static void * mmc_cim_read_write_block( struct mmc_dev *dev, int first )
{
	struct mmc_io_request *t = dev->io_request;
	struct mmc_response_r1 r1;
	struct mmc_slot *slot = dev->slot + t->id;
	int    retval = 0;
	int    i;

	DEBUG(2," first=%d\n",first);

	if ( first ) {
		mmc_fix_request_block_size( dev );

		switch ( slot->state ) {
		case CARD_STATE_STBY:
			mmc_simple_cmd(dev, MMC_SELECT_CARD, slot->rca, RESPONSE_R1B );
			break;
		case CARD_STATE_TRAN:
			mmc_simple_cmd(dev, MMC_SET_BLOCKLEN, t->block_len, RESPONSE_R1 );
			break;
		default:
			DEBUG(0,": invalid card state %d\n", slot->state);
			goto read_block_error;
			break;
		}
		return NULL;
	}

	switch (dev->request.cmd) {
	case MMC_SELECT_CARD:
		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )
			goto read_block_error;

		for ( i = 0 ; i < dev->num_slots ; i++ )
			dev->slot[i].state = ( i == t->id ? CARD_STATE_TRAN : CARD_STATE_STBY );
           
                if(slot->sd)
		{ 
                  slot->scr = 0;
		  mmc_simple_cmd(dev, MMC_APP_CMD,  slot->rca, RESPONSE_R1);
                }
                else
		{ 
                   mmc_simple_cmd(dev, MMC_SET_BLOCKLEN, t->block_len, RESPONSE_R1 );
                }
		break;

        case MMC_APP_CMD:
        	retval = mmc_unpack_r1(&dev->request,&r1,slot->state);

		if ( retval ) {
                   DEBUG(0, ": unable to MMC_APP_CMD error=%d (%s)\n", 
			      retval, mmc_result_to_string(retval));
                   goto read_block_error;
		}

                if (slot->scr & (1 << 18))
		{
		  mmc_simple_cmd(dev, SET_BUS_WIDTH,  2, RESPONSE_R1);
                }
                else if (slot->scr)
		{
                  mmc_simple_cmd(dev, SET_BUS_WIDTH, 0, RESPONSE_R1);
                }   
                else
		{       
		  /* Get SCR */
                  mmc_simple_cmd(dev, SEND_SCR, 0, RESPONSE_R1);
                }

		break;

	case SEND_SCR:
	        retval = mmc_unpack_scr(&dev->request, &r1, slot->state, &slot->scr);
                if ( retval ) {
                   DEBUG(0, ": unable to SEND_SCR error=%d (%s)\n", 
			      retval, mmc_result_to_string(retval));
                   goto read_block_error;
		}

                DEBUG(2, ": Get SCR from SD: 0x%x Satus: %x\n", slot->scr, r1.status);

                mmc_simple_cmd(dev, MMC_APP_CMD, slot->rca, RESPONSE_R1);
                break;

        case SET_BUS_WIDTH:
                retval = mmc_unpack_r1(&dev->request,&r1,slot->state);
                if ( retval ) {
                   DEBUG(0, ": unable to SET_BUS_WIDTH error=%d (%s)\n", 
			      retval, mmc_result_to_string(retval));
                   goto read_block_error; 
		}
		else
		{
                   mmc_simple_cmd(dev, MMC_SET_BLOCKLEN, t->block_len, RESPONSE_R1 );
		}    
                break;
              
	case MMC_SET_BLOCKLEN:
		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )
			goto read_block_error;

		mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_SINGLE_BLOCK : MMC_WRITE_BLOCK), 
			     t->sector * t->block_len, 1, t->block_len, RESPONSE_R1 );
		break;

	case MMC_READ_SINGLE_BLOCK:
	case MMC_WRITE_BLOCK:
		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) )
			goto read_block_error;

		t->nr_sectors--;
		t->sector++;
		t->buffer += t->block_len;

		if ( t->nr_sectors ) {
			mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_SINGLE_BLOCK : MMC_WRITE_BLOCK), 
				     t->sector * t->block_len, 1, t->block_len, RESPONSE_R1 );
		}
		else {
			mmc_finish_io_request( dev, 1 );
			if ( mmc_has_valid_request(dev) )
				return mmc_cim_read_write_block;
			return mmc_cim_default_state;
		}
		break;

	default:
		goto read_block_error;
		break;
	}
	return NULL;

read_block_error:
	DEBUG(0,": failure during cmd %d, error %d (%s)\n", 
	      dev->request.cmd, retval, mmc_result_to_string(retval));
	mmc_finish_io_request( dev, 0 );   // Failure
	return mmc_cim_default_state;
}
Esempio n. 4
0
static int mmc_init_card_state(struct mmc_request *request)
{
	struct mmc_response_r1 r1;
	struct mmc_response_r3 r3;
	int retval;
	int ocr = 0x40300000;

	DEBUG(2, "mmc_init_card_state\n");

	switch (request->cmd) {
	case MMC_GO_IDLE_STATE:	/* No response to parse */
		if (mmcinfo.sd)
			mmc_simple_cmd(request, 8, 0x1aa, RESPONSE_R1);
		else
			mmc_simple_cmd(request, MMC_SEND_OP_COND,
				       MMC_OCR_ARG, RESPONSE_R3);
		break;

	case 8:
		retval = mmc_unpack_r1(request, &r1, mmcinfo.state);
		mmc_simple_cmd(request, MMC_APP_CMD, 0, RESPONSE_R1);
		break;

	case MMC_APP_CMD:
		retval = mmc_unpack_r1(request, &r1, mmcinfo.state);

		if (retval & (limit_41 < 100)) {
			DEBUG(0,
			      "mmc_init_card_state: unable to MMC_APP_CMD error=%d (%s)\n",
			      retval, mmc_result_to_string(retval));
			limit_41++;
			mmc_simple_cmd(request, SD_SEND_OP_COND, ocr,
				       RESPONSE_R3);
		} else if (limit_41 < 100) {
			limit_41++;
			mmc_simple_cmd(request, SD_SEND_OP_COND, ocr,
				       RESPONSE_R3);
		} else {
			/* reset the card to idle */
			mmc_simple_cmd(request, MMC_GO_IDLE_STATE, 0,
				       RESPONSE_NONE);
			mmcinfo.sd = 0;
		}
		break;

	case SD_SEND_OP_COND:
		retval = mmc_unpack_r3(request, &r3);
		if (retval) {

			/* Try MMC card */
			mmc_simple_cmd(request, MMC_SEND_OP_COND,
				       MMC_OCR_ARG, RESPONSE_R3);
			break;
		}

		DEBUG(2, "mmc_init_card_state: read ocr value = 0x%08x\n",
		      r3.ocr);

		if (!(r3.ocr & MMC_CARD_BUSY || ocr == 0)) {
			mdelay(10);
			mmc_simple_cmd(request, MMC_APP_CMD, 0,
				       RESPONSE_R1);
		} else {
			/* Set the data bus width to 4 bits */
			mmcinfo.sd = 1;	/* SD Card ready */
			mmcinfo.state = CARD_STATE_READY;
			mmc_simple_cmd(request, MMC_ALL_SEND_CID, 0,
				       RESPONSE_R2_CID);
		}
		break;

	case MMC_SEND_OP_COND:
		retval = mmc_unpack_r3(request, &r3);
		if (retval) {
			DEBUG(0,
			      "mmc_init_card_state: failed SEND_OP_COND error=%d (%s)\n",
			      retval, mmc_result_to_string(retval));
			return MMC_INIT_FAILED;
		}

		DEBUG(2, "mmc_init_card_state: read ocr value = 0x%08x\n",
		      r3.ocr);
		if (!(r3.ocr & MMC_CARD_BUSY)) {
			mmc_simple_cmd(request, MMC_SEND_OP_COND,
				       MMC_OCR_ARG, RESPONSE_R3);
		} else {
			mmcinfo.sd = 0;	/* MMC Card ready */
			mmcinfo.state = CARD_STATE_READY;
			mmc_simple_cmd(request, MMC_ALL_SEND_CID, 0,
				       RESPONSE_R2_CID);
		}
		break;

	case MMC_ALL_SEND_CID:
		retval = mmc_unpack_cid(request, &mmcinfo.cid);

		/*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
		if (retval && (retval != MMC_ERROR_CRC)) {
			DEBUG(0,
			      "mmc_init_card_state: unable to ALL_SEND_CID error=%d (%s)\n",
			      retval, mmc_result_to_string(retval));
			return MMC_INIT_FAILED;
		}
		mmcinfo.state = CARD_STATE_IDENT;
		if (mmcinfo.sd)
			mmc_simple_cmd(request, MMC_SET_RELATIVE_ADDR, 0,
				       RESPONSE_R6);
		else
			mmc_simple_cmd(request, MMC_SET_RELATIVE_ADDR,
				       ID_TO_RCA(mmcinfo.id) << 16,
				       RESPONSE_R1);
		break;

	case MMC_SET_RELATIVE_ADDR:
		if (mmcinfo.sd) {
			retval =
			    mmc_unpack_r6(request, &r1, mmcinfo.state,
					  &mmcinfo.rca);
			mmcinfo.rca = mmcinfo.rca << 16;
			DEBUG(2,
			      "mmc_init_card_state: Get RCA from SD: 0x%04x Status: %x\n",
			      mmcinfo.rca, r1.status);
		} else {
			retval =
			    mmc_unpack_r1(request, &r1, mmcinfo.state);
			mmcinfo.rca = ID_TO_RCA(mmcinfo.id) << 16;
		}
		if (retval) {
			DEBUG(0,
			      "mmc_init_card_state: unable to SET_RELATIVE_ADDR error=%d (%s)\n",
			      retval, mmc_result_to_string(retval));
			return MMC_INIT_FAILED;
		}

		mmcinfo.state = CARD_STATE_STBY;
		mmc_simple_cmd(request, MMC_SEND_CSD, mmcinfo.rca,
			       RESPONSE_R2_CSD);

		break;
	case MMC_SEND_CSD:
		retval = mmc_unpack_csd(request, &mmcinfo.csd);

		/*FIXME:ignore CRC error for CMD2/CMD9/CMD10 */
		if (retval && (retval != MMC_ERROR_CRC)) {
			DEBUG(0,
			      "mmc_init_card_state: unable to SEND_CSD error=%d (%s)\n",
			      retval, mmc_result_to_string(retval));
			return MMC_INIT_FAILED;
		}
		if (mmcinfo.csd.dsr_imp) {
			DEBUG(0,
			      "mmc_init_card_state: driver doesn't support setting DSR\n");
		}
		mmc_configure_card();
		return MMC_INIT_PASSED;

		break;
	default:
		DEBUG(0,
		      "mmc_init_card_state: error!  Illegal last cmd %d\n",
		      request->cmd);
		return MMC_INIT_FAILED;
	}

	return MMC_INIT_DOING;
}