⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_disk.c

📁 linux 2.6下的sd卡驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
				controller->Registers->sd_POWER = MCI_POWER_OFF;		//InterruptDisable(SYSINTR_SD0);		//msleep(10);		{volatile int a; for(a=0; a<10000; a++); }	}	if (error)	{		//RETAILMSG(MSG_DISK, (_T("SD: SDI_ResetInterface - error:%d\r\n"), error));		if (errorcode)			*errorcode = error;		return	FALSE;	}	return TRUE;}//------------------------------------------------------------------------------//// Deinit interface - deinit the current device//// Arguments://		controller - handle for the instance.//		errorcode - record error. //// Functions: //		Realese DMA and close the interrupt event. ////------------------------------------------------------------------------------BOOL SDI_DeinitInterface(	SD_controller *controller, 	unsigned long *errorcode	){	unsigned long error = 0;	if (!controller)		error = 1;	if (!error)	{		SDI_ResetInterface(controller, 0);		if (controller->Registers)			iounmap((void*)controller->Registers);		/*		if (controller->InterruptEvent)			CloseHandle(controller->InterruptEvent);			*/		if (controller->SysDetect)			iounmap((void*)controller->SysDetect);	}	/*	if (!error)	{		SDI_ReleaseDMA();		if (DMAIntrEvent != NULL)		{			CloseHandle (DMAIntrEvent);			DMAIntrEvent = NULL;		}	}	*/	if (error)	{		//RETAILMSG(MSG_DISK, (_T("SD: SDI_DeinitInterface - error:%d\r\n"), error));		if (errorcode)			*errorcode = error;		return	FALSE;	}	return TRUE;}//------------------------------------------------------------------------------//// Send Command//// Arguments://		controller - handle for the instance.//		param - parameters of command.//		arg - arguments of command.//		response - return values if the command has response, or else ignored.//		errorcode - record error. //// Functions://		Send command to card. Then wait the interrupt. //		If the command has response, it will feed back response. Else it will //		send a command end signal. //		See also define of CommandParameters. ////------------------------------------------------------------------------------BOOL SDI_SendCmd(	SD_controller*controller, 	const Command_Parameter *param, 	unsigned long arg, 	apMCI_sResponse *response, 	unsigned long *errorcode	){	unsigned long error = 0;	unsigned long CommandData = 0;	BOOL TimeOut = FALSE;	SD_REG *regs;	if (!controller || !param)		error = 1;	regs = controller->Registers;	if (!regs)		error = 2;	if (!error)	{		BOOL cmdok = FALSE;		DECLARE_COMPLETION(comp);		regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;		/*construct command*/		apBIT_SET(CommandData,MCI_CMD_INDEX, param->CmdIndex);		apBIT_SET(CommandData,MCI_CMD_RESPONSE, param->Responsetype);		apBIT_SET(CommandData,MCI_CMD_INTERRUPT, param->CmdTimer);		apBIT_SET(CommandData,MCI_CMD_PENDING, (param->Option & MCI_CMDOPT_PENDING)!=0);		/*enable bit*/		CommandData |= apBIT_MASK(MCI_CMD_ENABLE);			//controller->cmddone_data = NULL;		controller->cmddone_data = &comp;		regs->sd_MASK0 = 0;		//InterruptDone(SYSINTR_SD0);		regs->sd_MASK0 = param->InterruptMask;		regs->sd_ARGUMENT = arg ; 		//ResetEvent(controller->InterruptEvent);		regs->sd_COMMAND  = CommandData;		wait_for_completion(&comp);		{			if (((controller->laststatus&apMCI_CMDSTAT_SENT) && (param->Responsetype == apMCI_CMDRESP_NONE)) || 				((controller->laststatus&apMCI_CMDSTAT_RESPOK) && (param->Responsetype != apMCI_CMDRESP_NONE)))			{				cmdok = TRUE;			}			else if (controller->laststatus & apMCI_CMDSTAT_FAIL)			{				error = 4;			}		}		controller->cmddone_data = NULL;		regs->sd_MASK0 = 0;		regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;		regs->sd_COMMAND  = 0;		regs->sd_ARGUMENT = apBITS_ALL;	}	if (response && (param->Responsetype!=apMCI_CMDRESP_NONE))	{		if (param->Responsetype == apMCI_CMDRESP_SHORT)			response->ShortResponse = regs->sd_RESP0;		else if (param->Responsetype == apMCI_CMDRESP_LONG)		{			response->LongResponse[0] = regs->sd_RESP0;			response->LongResponse[1] = regs->sd_RESP1;			response->LongResponse[2] = regs->sd_RESP2;			response->LongResponse[3] = regs->sd_RESP3;		}	}	if (error)	{		if (errorcode)			*errorcode = error;		return	FALSE;	}	return TRUE;}//------------------------------------------------------------------------------//// Decode long response//// Arguments://		pLongResponse - Pointer to a long response structure. //		LowestBit - Lowest bit to decode. //		BitWidth - How many bits to decode. //// Functions://		Intercept a segment in the long response. ////------------------------------------------------------------------------------unsigned long SDI_PrvLongResponseDecode(	apMCI_sResponse *pLongResponse,	unsigned long LowestBit,	unsigned long BitWidth	){	unsigned long Result;	unsigned long LowWordBits;		// bits in the low word 	//	RETAILMSG(MSG_DISK, (_T("SD: SDI_PrvLongResponseDecode+\r\n")));	// The low bits are in the last words of the response, so bit B lies in word 4-(B/32)	LowWordBits=32 - (LowestBit & 31);	Result=apBIT_GET_FIELD(		pLongResponse->LongResponse[3-(LowestBit>>5)],		MIN(BitWidth,LowWordBits),		LowestBit & 31		);	// Go to the next word and take some low bits from there	if (BitWidth > LowWordBits)	{		Result|=apBIT_GET_FIELD(			pLongResponse->LongResponse[2-(LowestBit>>5)],			BitWidth - LowWordBits,			0			)<<LowWordBits;	}//	RETAILMSG(MSG_DISK, (_T("SD: SDI_PrvLongResponseDecode-\r\n")));	return Result;                                   }//------------------------------------------------------------------------------//// Get card identification data//// Arguments://		controller - handle for the instance.//		pDecodedResponse - pointer to decode respond. //		errorcode - record error. ////------------------------------------------------------------------------------BOOL SDI_GetCID(	SD_controller *controller, 	apMCI_sDecodedCID *pDecodedResponse, 	unsigned long *errorcode	){	apMCI_sResponse  response, *pResponseData = &response;	unsigned long temp1, temp2, error = 0;	if (!controller || !pDecodedResponse)		error = 1;	if (!error)	{		int i=0;		while(!SDI_SendCmd(controller, &CommandParameters[ALL_SEND_CID], 0x0, &response, &error))		{			i++;			if(i%10==0){				error = 2;				break;			}			msleep(100);			/*{				volatile int a, b; 				for(a=0; a<100; a++);					for(b=0; b<10000; b++); 			}*/		}		if(i>1)			printk("%d times getcid ok\n", i);	}	if (!error)	{		pDecodedResponse->MID=			SDI_PrvLongResponseDecode(pResponseData,bsMCI_CID_MID,bwMCI_CID_MID);		// get Application ID		pDecodedResponse->OID=			SDI_PrvLongResponseDecode(pResponseData,bsMCI_CID_OID,bwMCI_CID_OID);				temp1 = SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_PNM_H,bwMCI_SD_CID_PNM_H);		temp2 = SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_PNM_L,bwMCI_SD_CID_PNM_L);				pDecodedResponse->PNM[0] = (unsigned char)apBIT_GET_FIELD(temp1, 8, 0);		pDecodedResponse->PNM[1] = (unsigned char)apBIT_GET_FIELD(temp2, 8, 24);		pDecodedResponse->PNM[2] = (unsigned char)apBIT_GET_FIELD(temp2, 8, 16);		pDecodedResponse->PNM[3] = (unsigned char)apBIT_GET_FIELD(temp2, 8, 8);		pDecodedResponse->PNM[4] = (unsigned char)apBIT_GET_FIELD(temp2, 8, 0);		pDecodedResponse->PNM[5] = 0;		pDecodedResponse->PNM[6] = 0;				// get Product Revision		pDecodedResponse->PRV=			SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_PRV,bwMCI_SD_CID_PRV);		// get Product Serial Number		pDecodedResponse->PSN=			SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_PSN,bwMCI_SD_CID_PSN);		// get Manufacturing Date		pDecodedResponse->MDT=			SDI_PrvLongResponseDecode(pResponseData,bsMCI_SD_CID_MDT,bwMCI_SD_CID_MDT);			}#if SD_DISK_DEBUG	{		int i;		printk("MID: %x\n", pDecodedResponse->MID);		printk("OID: %x\n", pDecodedResponse->OID);		printk("MID: ");		for (i=0; i<7; i++) {			printk("%x ", pDecodedResponse->PNM[i]);		}		printk("\n");		printk("PRV: %x\n", pDecodedResponse->PRV);		printk("PSN: %x\n", pDecodedResponse->PSN);		printk("MDT: %x\n", pDecodedResponse->MDT);	}#endif		if (error)	{		if (errorcode)			*errorcode = error;		return	FALSE;	}	return TRUE;}//------------------------------------------------------------------------------//// Get card specific data//// Arguments://		controller - handle for the instance.//		pDecodedResponse - pointer to decode respond. //		errorcode - record error. ////------------------------------------------------------------------------------BOOL SDI_GetCSD(	SD_controller *controller, 	apMCI_sDecodedCSD *pDecodedResponse, 	unsigned long RCA,	unsigned long *errorcode	){	unsigned long error = 0;	/* look up tables for calculating values in CSD register */	static const unsigned long TAACUnit[8] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000}; /* calculates as 0.1ns */	static const unsigned long TranSpeedUnit[8] = {10, 100, 1000, 10000, 0, 0, 0, 0};              /* calculates as kHz */	static const unsigned long Value[16] = {0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80};			apMCI_sResponse  response, *pResponseData = &response;	if (!controller || !pDecodedResponse)		error = 1;	if (!error)	{		if (!SDI_SendCmd(controller, &CommandParameters[SEND_CSD], RCA, &response, &error))		{			if (!SDI_SendCmd(controller, &CommandParameters[SEND_CSD], RCA, &response, &error))			{				error = 2;			}		}	}	if (!error)	{		pDecodedResponse->csd_structure = (unsigned char)SDI_PrvLongResponseDecode(pResponseData, bsMCI_CSD_STRUCTURE, bwMCI_CSD_STRUCTURE);		pDecodedResponse->crc = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_CRC, bwMCI_CSD_CRC);		pDecodedResponse->file_format = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_FILE_FORMAT, bwMCI_CSD_FILE_FORMAT);		pDecodedResponse->temporary_write_protection = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_TEMP_WP, bwMCI_CSD_TEMP_WP);		pDecodedResponse->permanent_write_protection = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_PERM_WP, bwMCI_CSD_PERM_WP);		pDecodedResponse->copy_flag = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_COPY, bwMCI_CSD_COPY);		pDecodedResponse->file_format_group = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_FILE_FORMAT_GRP, bwMCI_CSD_FILE_FORMAT_GRP);		if (pDecodedResponse->csd_structure == 0)		{			pDecodedResponse->erase_sector_size = 1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_ERASE_SECT_SD, bwMCI_CSD_ERASE_SECT_SD);		}		else		{			pDecodedResponse->erase_sector_size = (1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_ERASE_GRP_SIZE11, bwMCI_CSD_ERASE_GRP_SIZE11))				* (1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_ERASE_GRP_MULT11, bwMCI_CSD_ERASE_GRP_MULT11));		}				if (pDecodedResponse->csd_structure == 0)		{			pDecodedResponse->write_protect_group_size = 1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WP_GRP_SIZE, bwMCI_CSD_WP_GRP_SIZE);		}		else		{			pDecodedResponse->write_protect_group_size = 1 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WP_GRP_SIZE11, bwMCI_CSD_WP_GRP_SIZE11);		}    		pDecodedResponse->partial_blocks_for_write_allowed = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WTBLP, bwMCI_CSD_WTBLP);		pDecodedResponse->max_write_data_block_length = 1 << SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WTBL, bwMCI_CSD_WTBL);		pDecodedResponse->write_speed_factor = 1 << SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_R2W, bwMCI_CSD_R2W);		pDecodedResponse->write_protect_group_enable = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WP_GRP_ENABLE, bwMCI_CSD_WP_GRP_ENABLE);		pDecodedResponse->erase_single_block_enable = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_ERASE_SINGLE_BLOCK_ENABLE, bwMCI_CSD_ERASE_SINGLE_BLOCK_ENABLE);		pDecodedResponse->device_size_multiplier = 1 << (2 + SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_CMULT, bwMCI_CSD_CMULT));		pDecodedResponse->max_write_current_max = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_VDD_W_CURR_MAX, bwMCI_CSD_VDD_W_CURR_MAX);		pDecodedResponse->max_write_current_min = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_VDD_W_CURR_MIN, bwMCI_CSD_VDD_W_CURR_MIN);		pDecodedResponse->max_read_current_max = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_VDD_R_CURR_MAX, bwMCI_CSD_VDD_R_CURR_MAX);		pDecodedResponse->max_read_current_min = (unsigned char)SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_VDD_R_CURR_MIN, bwMCI_CSD_VDD_R_CURR_MIN);		pDecodedResponse->device_size = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_CSIZE, bwMCI_CSD_CSIZE);		pDecodedResponse->dsr_implemented = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_DSR_IMP, bwMCI_CSD_DSR_IMP);		pDecodedResponse->read_block_misalignment = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_RDBLMIS, bwMCI_CSD_RDBLMIS);		pDecodedResponse->write_block_misalignment = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_WTBLMIS, bwMCI_CSD_WTBLMIS);		pDecodedResponse->partial_blocks_for_read_allowed = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_RDBLP, bwMCI_CSD_RDBLP);		pDecodedResponse->max_read_data_block_length = 1 << SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_RDBL, bwMCI_CSD_RDBL);		pDecodedResponse->card_command_classes = SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_CCC, bwMCI_CSD_CCC);		pDecodedResponse->max_data_transfer_rate_khz = TranSpeedUnit[SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_MAXTRANLO, bwMCI_CSD_MAXTRANLO)]			* Value[SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_MAXTRANHI, bwMCI_CSD_MAXTRANHI)];		pDecodedResponse->data_read_access_time_2_in_clk_cycles = 100 * SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_NSAC, bwMCI_CSD_NSAC);				pDecodedResponse->data_read_access_time_1_tns = TAACUnit[SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_TAACLO, bwMCI_CSD_TAACLO)]			* Value[SDI_PrvLongResponseDecode(  pResponseData, bsMCI_CSD_TAACHI, bwMCI_CSD_TAACHI)];				pDecodedResponse->CardSize = (pDecodedResponse->device_size + 1)			*  pDecodedResponse->device_size_multiplier			*  pDecodedResponse->max_read_data_block_length;	}	if (error)	{		if (errorcode)			*errorcode = error;		return	FALSE;	}#if SD_DISK_DEBUG	{		printk("device_size: %x\n", pDecodedResponse->device_size);		printk("device_size_multiplier: %x\n", pDecodedResponse->device_size_multiplier);		printk("max_read_data_block_length: %x\n", pDecodedResponse->max_read_data_block_length);		printk("CardSize: %x\n", pDecodedResponse->CardSize);	}		{		printk("csd_struct: %x\n", pDecodedResponse->csd_structure);		printk("data_read_access_time_1_tns: %x\n", pDecodedResponse->data_read_access_time_1_tns);		printk("data_read_access_time_2_in_clk_cycles: %x\n", pDecodedResponse->data_read_access_time_2_in_clk_cycles);		printk("max_data_transfer_rate_khz: %x\n", pDecodedResponse->max_data_transfer_rate_khz);		printk("card_command_classes: %x\n", pDecodedResponse->card_command_classes);		printk("max_read_data_block_length: %x\n", pDecodedResponse->max_read_data_block_length);		printk("partial_blocks_for_read_allowed: %x\n", pDecodedResponse->partial_blocks_for_read_allowed);		printk("write_block_misalignment: %x\n", pDecodedResponse->write_block_misalignment);		printk("read_block_misalignment: %x\n", pDecodedResponse->read_block_misalignment);		printk("dsr_implemented: %x\n", pDecodedResponse->dsr_implemented);		printk("device_size: %x\n", pDecodedResponse->device_size);		printk("max_read_current_min: %x\n", pDecodedResponse->max_read_current_min);		printk("max_read_current_max: %x\n", pDecodedResponse->max_read_current_max);		printk("max_write_current_min: %x\n", pDecodedResponse->max_write_current_min);		printk("max_write_current_max: %x\n", pDecodedResponse->max_write_current_max);		printk("device_size_multiplier: %x\n", pDecodedResponse->device_size_multiplier);		printk("erase_single_block_enable: %x\n", pDecodedResponse->erase_single_block_enable);		//todo::	}#endif		return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -