Example #1
0
static int scsiTestUnitReady(struct SBP2Device* dev){
	struct CommandDescriptorBlock cdb;

	XPRINTF("IEEE1394_disk: scsiTestUnitReady.\n");

	cdb.misc=(u32)(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(dev->max_payload) | CDB_DIRECTION(WRITE_TRANSACTION) | CDB_SPEED(dev->speed));

	cdb.DataDescriptor.low=cdb.DataDescriptor.high=0;
	cdb.DataDescriptor.NodeID=dev->InitiatorNodeID;

	cdb.NextOrb.high=cdb.NextOrb.low=0;
	cdb.NextOrb.reserved=NULL_POINTER;

	//scsi command packet
	cdb.CDBs[3] = 0x00;		//test unit ready operation code
	cdb.CDBs[2] = 0;		//reserved
	cdb.CDBs[1] = 0;		//reserved
	cdb.CDBs[0] = 0;		//reserved
	cdb.CDBs[7] = 0;		//reserved
	cdb.CDBs[6] = 0;		//reserved
	cdb.CDBs[5] = 0;		//reserved
	cdb.CDBs[4] = 0;		//reserved
	cdb.CDBs[11] = 0;		//reserved
	cdb.CDBs[10] = 0;		//reserved
	cdb.CDBs[9] = 0;		//reserved
	cdb.CDBs[8] = 0;		//reserved

    	ieee1394_SendCommandBlockORB(dev, &cdb);
	return(ieee1394_Sync());
}
Example #2
0
static int scsiReadCapacity(struct SBP2Device* dev, void *buffer, int size)
{
	struct CommandDescriptorBlock cdb;

	XPRINTF("IEEE1394_disk: scsiReadCapacity.\n");

	cdb.misc=(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(dev->max_payload) | CDB_DIRECTION(WRITE_TRANSACTION) | CDB_SPEED(dev->speed) | CDB_DATA_SIZE(size));

	cdb.DataDescriptor.low=(u32)buffer;
	cdb.DataDescriptor.high=0;
	cdb.DataDescriptor.NodeID=dev->InitiatorNodeID;

	cdb.NextOrb.high=cdb.NextOrb.low=0;
	cdb.NextOrb.reserved=NULL_POINTER;

	//scsi command packet
	cdb.CDBs[3] = 0x25;		//read capacity operation code
	cdb.CDBs[2] = 0;		//reserved
	cdb.CDBs[1] = 0;		//LBA 1
	cdb.CDBs[0] = 0;		//LBA 2
	cdb.CDBs[7] = 0;		//LBA 3
	cdb.CDBs[6] = 0;		//LBA 4
	cdb.CDBs[5] = 0;		//Reserved
	cdb.CDBs[4] = 0;		//Reserved
	cdb.CDBs[11] = 0;		//Reserved
	cdb.CDBs[10] = 0;		//reserved
	cdb.CDBs[9] = 0;		//reserved
	cdb.CDBs[8] = 0;		//reserved

     	ieee1394_SendCommandBlockORB(dev, &cdb);
	return(ieee1394_Sync());
}
Example #3
0
static int scsiStartStopUnit(struct SBP2Device* dev)
{
	struct CommandDescriptorBlock cdb;

	XPRINTF("IEEE1394_disk: scsiStartStopUnit.\n");

	cdb.misc=(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(dev->max_payload) | CDB_DIRECTION(WRITE_TRANSACTION) | CDB_SPEED(dev->speed));

	cdb.DataDescriptor.low=cdb.DataDescriptor.high=0;
	cdb.DataDescriptor.NodeID=dev->InitiatorNodeID;

	cdb.NextOrb.high=cdb.NextOrb.low=0;
	cdb.NextOrb.reserved=NULL_POINTER;

	//scsi command packet
	cdb.CDBs[3] = 0x1B;		//start stop unit operation code
	cdb.CDBs[2] = 1;		//reserved/immed
	cdb.CDBs[1] = 0;		//reserved
	cdb.CDBs[0] = 0;		//reserved
	cdb.CDBs[7] = 1;		//POWER CONDITIONS/reserved/LoEj/Start "Start the media and acquire the format type"
	cdb.CDBs[6] = 0;		//reserved
	cdb.CDBs[5] = 0;		//reserved
	cdb.CDBs[4] = 0;		//reserved
	cdb.CDBs[11] = 0;		//reserved
	cdb.CDBs[10] = 0;		//reserved
	cdb.CDBs[9] = 0;		//reserved
	cdb.CDBs[8] = 0;		//reserved

     	ieee1394_SendCommandBlockORB(dev, &cdb);
	return(ieee1394_Sync());
}
Example #4
0
static int scsiInquiry(struct SBP2Device* dev, void *buffer, int size)
{
	int ret;
	struct CommandDescriptorBlock cdb;
	unsigned int i;

	XPRINTF("IEEE1394_disk: scsiInquiry. buffer: %p\n", buffer);

	cdb.misc=(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(dev->max_payload) | CDB_DIRECTION(WRITE_TRANSACTION) | CDB_SPEED(dev->speed) | CDB_DATA_SIZE(size));

	cdb.DataDescriptor.low=(u32)buffer;
	cdb.DataDescriptor.high=0;
	cdb.DataDescriptor.NodeID=dev->InitiatorNodeID;

	cdb.NextOrb.high=cdb.NextOrb.low=0;
	cdb.NextOrb.reserved=NULL_POINTER;

	//scsi command packet
	cdb.CDBs[3] = 0x12;		//inquiry operation code
	cdb.CDBs[2] = 0;		//reserved
	cdb.CDBs[1] = 0;		//page code
	cdb.CDBs[0] = 0;		//reserved
	cdb.CDBs[7] = size;		//inquiry reply length
	cdb.CDBs[6] = 0;		//reserved
	cdb.CDBs[5] = 0;		//reserved
	cdb.CDBs[4] = 0;		//reserved
	cdb.CDBs[11] = 0;		//reserved
	cdb.CDBs[10] = 0;		//reserved
	cdb.CDBs[9] = 0;		//reserved
	cdb.CDBs[8] = 0;		//reserved

    	ieee1394_SendCommandBlockORB(dev, &cdb);
	ret=ieee1394_Sync();

	if(ret != 0) XPRINTF("IEEE1394_disk: scsiInquiry error %d\n", ret);
	else{
		for(i=0; i<size/4; i++) ((unsigned int *)buffer)[i]=BSWAP32(((unsigned int *)buffer)[i]);
	}

	return ret;
}
Example #5
0
static int ieee1394_InitializeFetchAgent(struct SBP2Device *dev){
	int result, retries;
	void *dummy_ORB;
	struct sbp2_pointer address;

	XPRINTF("Initializing fetch agent...");

	dummy_ORB=malloc(dev->ORB_size*4);
	memset(dummy_ORB, 0, dev->ORB_size*4);

	ieee1394_ResetFetchAgent(dev);

	/* Write the address of the dummy ORB to the fetch agent's ORB_POINTER register. */
	address.low=(u32)dummy_ORB;
	address.NodeID=dev->InitiatorNodeID;
	address.high=0;

	((struct sbp2_ORB_pointer *)dummy_ORB)->reserved=NULL_POINTER;
	((struct sbp2_ORB_pointer *)dummy_ORB)->high=((struct sbp2_ORB_pointer *)dummy_ORB)->low=0;
	((struct management_ORB *)dummy_ORB)->flags=(u32)(ORB_NOTIFY|ORB_REQUEST_FORMAT(3));

	retries=0;
	while((result=iLinkTrWrite(dev->trContext, dev->CommandBlockAgent_high, dev->CommandBlockAgent_low+0x08, &address, 8))<0){
		XPRINTF("Error writing to the Fetch Agent's ORB_POINTER register @ 0x%08lx %08lx. Code: %d.\n", dev->CommandBlockAgent_high, dev->CommandBlockAgent_low+0x08, result);
		ieee1394_ResetFetchAgent(dev);

		retries++;
		if(retries>3) return(-1);
	}

	result=ieee1394_Sync();
	ieee1394_GetFetchAgentState(dev);

	free(dummy_ORB);

	XPRINTF("done!\n");

	return 1;
}
Example #6
0
static int scsiRequestSense(struct SBP2Device* dev, void *buffer, int size)
{
	int ret;
	struct CommandDescriptorBlock cdb;

	XPRINTF("IEEE1394_disk: scsiRequestSense.\n");

	cdb.misc=(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(dev->max_payload) | CDB_DIRECTION(WRITE_TRANSACTION) | CDB_SPEED(dev->speed) | CDB_DATA_SIZE(size));

	cdb.DataDescriptor.low=(u32)buffer;
	cdb.DataDescriptor.high=0;
	cdb.DataDescriptor.NodeID=dev->InitiatorNodeID;

	cdb.NextOrb.high=cdb.NextOrb.low=0;
	cdb.NextOrb.reserved=NULL_POINTER;

	//scsi command packet
	cdb.CDBs[3] = 0x03;		//request sense operation code
	cdb.CDBs[2] = 0;		//reserved
	cdb.CDBs[1] = 0;		//reserved
	cdb.CDBs[0] = 0;		//reserved
	cdb.CDBs[7] = size;		//allocation length
	cdb.CDBs[6] = 0;		//reserved
	cdb.CDBs[5] = 0;		//reserved
	cdb.CDBs[4] = 0;		//reserved
	cdb.CDBs[11] = 0;		//reserved
	cdb.CDBs[10] = 0;		//reserved
	cdb.CDBs[9] = 0;		//reserved
	cdb.CDBs[8] = 0;		//reserved

    	ieee1394_SendCommandBlockORB(dev, &cdb);
	ret=ieee1394_Sync();

	if(ret!=0) XPRINTF("IEEE1394_disk: scsiRequestSense error: %d\n", ret);

    return ret;
}
Example #7
0
static int ieee1394_SendManagementORB(int mode, struct SBP2Device *dev){
	int result;
	struct sbp2_pointer address;

	struct sbp2_login_response login_result;
	struct management_ORB new_management_ORB;

	memset((unsigned char *)statusFIFO, 0, sizeof(statusFIFO));
	memset(&login_result, 0, sizeof(struct sbp2_login_response));
	memset(&new_management_ORB, 0, sizeof(struct management_ORB));

	new_management_ORB.status_FIFO.low=(u32)statusFIFO;

	((struct login_req *)&new_management_ORB)->flags=(u32)(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) |MANAGEMENT_ORB_FUNCTION(mode));

	switch(mode){
		case SBP2_LOGIN_REQUEST: /* Login. */
			/* The reconnect timeout is now set to 0, since the mechanism that determines whether the initiator was already logged into the target or not was not accurate. */
			((struct login_req *)&new_management_ORB)->flags|=(u32)(MANAGEMENT_ORB_RECONNECT(0) | MANAGEMENT_ORB_EXCLUSIVE(1) | MANAGEMENT_ORB_LUN(dev->LUN));

			((struct login_req *)&new_management_ORB)->login_response.low=(u32)&login_result;
			((struct login_req *)&new_management_ORB)->length=(MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(struct sbp2_login_response))|MANAGEMENT_ORB_PASSWORD_LENGTH(0));
			break;
#if 0
		case SBP2_RECONNECT_REQUEST: /* Reconnect. */
			((struct login_req *)&new_management_ORB)->flags|=(u32)(MANAGEMENT_ORB_RECONNECT(4) | MANAGEMENT_ORB_LOGINID(dev->loginID)); /* loginID was stored as a big endian number, so it has to be converted into little endian first. :( */
			break;
#endif
		default:
			XPRINTF("Warning! Unsupported management ORB type!\n");
	}

	address.NodeID=dev->InitiatorNodeID;
	address.high=0;
	address.low=(u32)&new_management_ORB;

	XPRINTF("Management ORB: %p. size=%d.\n", &new_management_ORB, sizeof(struct management_ORB));
	XPRINTF("Address pointer: %p\n", &address);

	if((result=iLinkTrWrite(dev->trContext, dev->ManagementAgent_high, dev->ManagementAgent_low, &address, 8))<0){ /* Write the Login ORB address to the target's Management Agent CSR. */
		XPRINTF("Error writing to the Management Agent CSR @ 0x%08lx %08lx. Code: %d.\n", dev->ManagementAgent_high, dev->ManagementAgent_low, result);
		return(result);
	}

	XPRINTF("Waiting for ILINK...\n");

	result=ieee1394_Sync_withTimeout(dev->mgt_ORB_timeout);

	XPRINTF("statusFIFO= %p; [0]=%u.\n", statusFIFO, statusFIFO[0]);
	if(result>=0){
		switch(mode){
			case SBP2_LOGIN_REQUEST: /* Login. */
					XPRINTF("Done. command_block_agent= 0x%08x %08lx.\n", login_result.command_block_agent.high, login_result.command_block_agent.low);

					/* Store the address to the target's command block agent. */

					dev->CommandBlockAgent_high=login_result.command_block_agent.high;
					dev->CommandBlockAgent_low=login_result.command_block_agent.low;

					dev->loginID=login_result.login_ID; /* Store the login ID. */

					XPRINTF("Login response size: %u.", login_result.length);
					XPRINTF("Signed into SBP-2 device node 0x%08x. Login ID: %u\n", dev->nodeID, dev->loginID);
				break;
#if 0
			case SBP2_RECONNECT_REQUEST: /* Reconnect. */
					/* Just return the result from ieee1394_Sync(). */
				break;
#endif
			default:
				XPRINTF("Warning! Unsupported management ORB type!\n");
		}

		/* Validate the fetch agent's CSR address. */
		if((dev->CommandBlockAgent_low<0xF0010000)||((dev->CommandBlockAgent_high&0xFFFF)!=0x0000FFFF)) result=(-1);
	}

	return result;
}
Example #8
0
int scsiWriteSector(struct SBP2Device *dev, unsigned long int lba, void* buffer, int sectorCount)
{
	unsigned int nOrbs, OrbsRemaining, i, sectorsToRead, sectorsRemaining, SectorsPerBlock;
	unsigned long int startingLBA;
	void *bufferPtr;
	int result, max_payload;

	XPRINTF("IEEE1394_disk: scsiWriteSector.\n");
	SectorsPerBlock=XFER_BLOCK_SIZE/dev->sectorSize;
	OrbsRemaining=sectorCount/SectorsPerBlock;
	if((sectorCount%SectorsPerBlock)!=0) OrbsRemaining++;

	startingLBA=lba;
	sectorsRemaining=sectorCount;
	bufferPtr=buffer;
	max_payload=(dev->max_payload>7)?7:dev->max_payload;	/* Do not allow the maximum payload to exceed 512 bytes (Actually, is this necessary?). */

	result=0;
	for(; (OrbsRemaining>0) && (result==0); OrbsRemaining-=nOrbs){
		nOrbs=(OrbsRemaining>MAX_ORBS)?MAX_ORBS:OrbsRemaining;

		for(i=0; i<nOrbs; i++){
			sectorsToRead=(sectorsRemaining>SectorsPerBlock)?SectorsPerBlock:sectorsRemaining;

			cdb[i].misc=(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(max_payload) | CDB_DIRECTION(READ_TRANSACTION) | CDB_SPEED(dev->speed) | CDB_DATA_SIZE((dev->sectorSize * sectorsToRead)));

			cdb[i].DataDescriptor.low=(u32)bufferPtr;
			cdb[i].DataDescriptor.high=0;
			cdb[i].DataDescriptor.NodeID=dev->InitiatorNodeID;

			if(i>0){
				cdb[i-1].NextOrb.high=0;
				cdb[i-1].NextOrb.low=(u32)&cdb[i];
				cdb[i-1].NextOrb.reserved=0;
			}

			//scsi command packet
			cdb[i].CDBs[3] = 0x2A;				//write operation code
			cdb[i].CDBs[2] = 0;				//Reserved
			cdb[i].CDBs[1] = (startingLBA & 0xFF000000) >> 24;	//lba 1 (MSB)
			cdb[i].CDBs[0] = (startingLBA & 0xFF0000) >> 16;	//lba 2
			cdb[i].CDBs[7] = (startingLBA & 0xFF00) >> 8;		//lba 3
			cdb[i].CDBs[6] = (startingLBA & 0xFF);			//lba 4 (LSB)
			cdb[i].CDBs[5] = 0;				//Reserved
			cdb[i].CDBs[4] = (sectorsToRead & 0xFF00) >> 8;	//Transfer length MSB
			cdb[i].CDBs[11] = (sectorsToRead & 0xFF);	//Transfer length LSB
			cdb[i].CDBs[10] = 0;				//reserved
			cdb[i].CDBs[9] = 0;				//reserved
			cdb[i].CDBs[8] = 0;				//reserved

			startingLBA+=sectorsToRead;
			sectorsRemaining-=sectorsToRead;
			bufferPtr+=dev->sectorSize * sectorsToRead;
		}

		/* NULL terminate the last ORB. */
		cdb[i-1].NextOrb.high=cdb[i-1].NextOrb.low=0;
		cdb[i-1].NextOrb.reserved=NULL_POINTER;

     		ieee1394_SendCommandBlockORB(dev, cdb);
		result=ieee1394_Sync();
	}

	return result;
}
Example #9
0
int scsiReadSector(struct SBP2Device *dev, unsigned long int lba, void *buffer, int sectorCount)
{
	unsigned int nOrbs, OrbsRemaining, i, sectorsToRead, sectorsRemaining, SectorsPerBlock, BlockNum;
	unsigned long int startingLBA;
	void *bufferPtr, *PreviousReqBufferPtr;
	int result;

	XPRINTF("IEEE1394_disk: scsiReadSector. buffer: %p, lba: 0x%08lx, numsectors: %d.\n", buffer, lba, sectorCount);
	SectorsPerBlock=XFER_BLOCK_SIZE/dev->sectorSize;
	OrbsRemaining=sectorCount/SectorsPerBlock;
	if((sectorCount%SectorsPerBlock)!=0) OrbsRemaining++;

	XPRINTF("NumOrbs=%d cdb: %p.\n", OrbsRemaining, cdb);

	startingLBA=lba;
	sectorsRemaining=sectorCount;
	bufferPtr=buffer;

	result=0;
	for(PreviousReqBufferPtr=NULL, BlockNum=0, sectorsToRead=0; (OrbsRemaining>0) && (result==0); OrbsRemaining-=nOrbs, BlockNum++){
		nOrbs=(OrbsRemaining>MAX_ORBS)?MAX_ORBS:OrbsRemaining;

		if(BlockNum>0){	/* While waiting for the read request that was just sent to be processed, byte-swap the previously read in data. */
			for(i=0; i<sectorsToRead<<7; i++) ((unsigned int *)PreviousReqBufferPtr)[i]=BSWAP32(((unsigned int *)PreviousReqBufferPtr)[i]);
			result=ieee1394_Sync();	/* Only sync if a read request is being processed. Otherwise, it'll wait eternally.. */
		}

		/* Save the current pointer to the buffer, so that the code above can byte-swap the payload of the request below that will be read in,
			when this loop loops around.
		*/
		PreviousReqBufferPtr=bufferPtr;

		for(i=0; i<nOrbs; i++){
			sectorsToRead=(sectorsRemaining>SectorsPerBlock)?SectorsPerBlock:sectorsRemaining;

			cdb[i].misc=(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(dev->max_payload) | CDB_DIRECTION(WRITE_TRANSACTION) | CDB_SPEED(dev->speed) | CDB_DATA_SIZE((dev->sectorSize * sectorsToRead)));

			cdb[i].DataDescriptor.low=(u32)bufferPtr;
			cdb[i].DataDescriptor.high=0;
			cdb[i].DataDescriptor.NodeID=dev->InitiatorNodeID;

			if(i>0){
				cdb[i-1].NextOrb.high=0;
				cdb[i-1].NextOrb.low=(u32)&cdb[i];
				cdb[i-1].NextOrb.reserved=0;
			}

			//scsi command packet
			cdb[i].CDBs[3] = 0x28;				//read operation code
			cdb[i].CDBs[2] = 0;				//Reserved
			cdb[i].CDBs[1] = (startingLBA & 0xFF000000) >> 24;	//lba 1 (MSB)
			cdb[i].CDBs[0] = (startingLBA & 0xFF0000) >> 16;	//lba 2
			cdb[i].CDBs[7] = (startingLBA & 0xFF00) >> 8;		//lba 3
			cdb[i].CDBs[6] = (startingLBA & 0xFF);			//lba 4 (LSB)
			cdb[i].CDBs[5] = 0;				//Reserved
			cdb[i].CDBs[4] = (sectorsToRead & 0xFF00) >> 8;	//Transfer length MSB
			cdb[i].CDBs[11] = (sectorsToRead & 0xFF);	//Transfer length LSB
			cdb[i].CDBs[10] = 0;				//reserved
			cdb[i].CDBs[9] = 0;				//reserved
			cdb[i].CDBs[8] = 0;				//reserved

			startingLBA+=sectorsToRead;
			sectorsRemaining-=sectorsToRead;
			bufferPtr+=dev->sectorSize * sectorsToRead;
		}

		/* NULL terminate the last ORB. */
		cdb[i-1].NextOrb.high=cdb[i-1].NextOrb.low=0;
		cdb[i-1].NextOrb.reserved=NULL_POINTER;

     		ieee1394_SendCommandBlockORB(dev, cdb);
	}

	/* Sync and byte-swap the last block. */
	result=ieee1394_Sync();
	for(i=0; i<sectorsToRead<<7; i++) ((unsigned int *)PreviousReqBufferPtr)[i]=BSWAP32(((unsigned int *)PreviousReqBufferPtr)[i]);

	XPRINTF("IEEE1394_disk: scsiReadSector done.\n");

	return result;
}