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
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 #8
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;
}