Exemplo n.º 1
0
//--------------------------------------------------------------
int _McWritePage(void *rpc_buf)
{
	g_descParam_t *dP = (g_descParam_t *)rpc_buf;
	register int fastsize, i, j;
	SifRpcReceiveData_t	rD;
	u8 eccbuf[16];

#ifdef DEBUG
	DPRINTF("mcserv: _McWritePage port%d slot%d page %d\n", dP->port, dP->slot, dP->fd);
#endif

	fastsize = ((u32)dP->buffer) & 0xf;
	if (fastsize == 0)
		goto fullpage;

	sceSifGetOtherData(&rD, (void *)(dP->buffer - (fastsize - 16)), &mcserv_buf, 496, 0);

	i = fastsize;
	while (i < 16) {
		mcserv_buf[i] = dP->data[i - fastsize];
		i++;
	}

	if (fastsize == 0)
		goto ecc_calc;


	j = 16;
	i = 0;
	while (i < fastsize) {
		mcserv_buf[496 + j] = dP->data[j - fastsize];
		i++;
		j++;
	}

	goto ecc_calc;

fullpage:

	sceSifGetOtherData(&rD, dP->buffer, &mcserv_buf, 512, 0);

ecc_calc:

	McDataChecksum((void *)(mcserv_buf + fastsize), &eccbuf[0]);
	McDataChecksum(&mcserv_buf[128], &eccbuf[3]);
	McDataChecksum(&mcserv_buf[256], &eccbuf[6]);
	McDataChecksum(&mcserv_buf[384], &eccbuf[9]);

	return McWritePage((dP->port & 1) | 2, dP->slot, dP->fd, (void *)(mcserv_buf + fastsize), eccbuf);
}
Exemplo n.º 2
0
int WriteBlock(int port, int slot, unsigned short int PageSize, unsigned short int BlockSize, unsigned int block, void *buffer){
	unsigned char *ECC_data;
	unsigned int i, ECCBlockLen, ECCBlockSect;
	int result;

	ECCBlockLen=PageSize/32; /* Size calculated based on information extracted from Jimmikaelkael's MCMAN module */

	if((ECC_data=malloc(ECCBlockLen))!=NULL){
		memset(ECC_data, 0, ECCBlockLen);

		/* If someone can tell me how the EraseBlock function really works, that will be informative. The Sony MCSERV module calculates the checksum of the block to be written separately.
			So since EraseBlock probably doesn't calculate the checksums of the blocks... what does it really calculate?
		*/
		if((result=McEraseBlock(port, 0, block, NULL, NULL))>=0){
			for(i=0; i<BlockSize; i++){
				/* Manually calculate the ECC for each 128-byte block for each page of the block to be written. See the comment above for more details. */
				for(ECCBlockSect=0; ECCBlockSect<(PageSize/128); ECCBlockSect++) McDataChecksum(&((unsigned char *)buffer)[i*PageSize+ECCBlockSect*128], &ECC_data[ECCBlockSect*3]);

				if((result=McWritePage(port, slot, block*BlockSize+i, &((unsigned char *)buffer)[i*PageSize], ECC_data))!=sceMcResSucceed){
					break;
				}
			}
		}

		free(ECC_data);
	}
	else result=-ENOMEM;

	return result;
}
Exemplo n.º 3
0
//--------------------------------------------------------------
int _McEraseBlock(void *rpc_buf)
{
	g_descParam_t *dP = (g_descParam_t *)rpc_buf;
	register int pagenum, r;
	u8 eccbuf[16];

#ifdef DEBUG
	DPRINTF("mcserv: _McEraseBlock port%d slot%d offset %d\n", dP->port, dP->slot, dP->offset);
#endif

	dP->port = (dP->port & 1) + 2;

	if (McGetMcType(dP->port, dP->slot) == 2) {
		r = McEraseBlock(dP->port, dP->offset, NULL, NULL);
		if (r != 0)
			return r;

		if (dP->origin == -1)
			return r;

		memset(mcserv_buf, dP->origin, 512);

		McDataChecksum(&mcserv_buf[0], &eccbuf[0]);
		McDataChecksum(&mcserv_buf[128], &eccbuf[3]);
		McDataChecksum(&mcserv_buf[256], &eccbuf[6]);
		McDataChecksum(&mcserv_buf[384], &eccbuf[9]);

		pagenum = 0;

		do {
			r = McWritePage(dP->port, dP->slot, (dP->offset << 4) + pagenum, mcserv_buf, eccbuf);

		} while (++pagenum < 16);   // <-- and the last page of the block ???

		return r;

	}

	memset(mcserv_buf, dP->origin, 128);

	r = McWritePS1PDACard(dP->port, dP->slot, dP->offset, mcserv_buf);

	return r;
}
Exemplo n.º 4
0
//--------------------------------------------------------------
int mcman_eraseblock(int port, int slot, int block, void **pagebuf, void *eccbuf)
{
	register int retries, size, ecc_offset;
	int page;
	u8 *p = mcman_sio2packet.out_dma.addr;
	void *p_ecc;
	register MCDevInfo *mcdi = &mcman_devinfos[port][slot];

	page = block * mcdi->blocksize;

	sio2packet_add(port, slot, 0xffffffff, NULL);
	sio2packet_add(port, slot, 0x02, (u8 *)&page);
	sio2packet_add(port, slot, 0x0d, NULL);
	sio2packet_add(port, slot, 0xfffffffe, NULL);

	retries = 0;
	do {
		mcman_sio2transfer(port, slot, &mcman_sio2packet);

		if (((mcman_sio2packet.stat6c & 0xF000) != 0x1000) || (p[8] != 0x5a))
			continue;

		if (p[0x93] == p[8])
			break;
	} while (++retries < 5);

	if (retries >= 5)
		return sceMcResChangedCard;

	if (pagebuf && eccbuf) { // This part leave the first ecc byte of each block page in eccbuf
		mcman_wmemset(eccbuf, 32, 0);

		page = 0;
		while (page < mcdi->blocksize) {
			ecc_offset = page * mcdi->pagesize;
			if (ecc_offset < 0)
				ecc_offset += 0x1f;
			ecc_offset = ecc_offset >> 5;
			p_ecc = (void *)(eccbuf + ecc_offset);
			size = 0;
			while (size < mcdi->pagesize)	{
				if (*pagebuf)
					McDataChecksum((void *)(*pagebuf + size), p_ecc);
				size += 128;
				p_ecc += 3;
			}
			pagebuf++;
			page++;
		}
	}