13#include "usbhd_common.h"
15#include "part_driver.h"
16#include "mass_debug.h"
19static int scsiTestUnitReady(
struct SBP2Device *dev);
20static int scsiInquiry(
struct SBP2Device *dev,
void *buffer,
int size);
21static int scsiRequestSense(
struct SBP2Device *dev,
void *buffer,
int size);
22static int scsiStartStopUnit(
struct SBP2Device *dev);
23static int scsiReadCapacity(
struct SBP2Device *dev,
void *buffer,
int size);
25static int scsiTestUnitReady(
struct SBP2Device *dev)
29 XPRINTF(
"scsiTestUnitReady.\n");
31 cdb.misc = (u32)(ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(dev->max_payload) | CDB_DIRECTION(WRITE_TRANSACTION) | CDB_SPEED(dev->speed));
33 cdb.DataDescriptor.low = cdb.DataDescriptor.high = 0;
34 cdb.DataDescriptor.NodeID = dev->InitiatorNodeID;
36 cdb.NextOrb.high = cdb.NextOrb.low = 0;
37 cdb.NextOrb.reserved = NULL_POINTER;
53 ieee1394_SendCommandBlockORB(dev, &cdb);
54 return (ieee1394_Sync());
57static int scsiRequestSense(
struct SBP2Device *dev,
void *buffer,
int size)
62 XPRINTF(
"scsiRequestSense.\n");
64 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));
66 cdb.DataDescriptor.low = (u32)buffer;
67 cdb.DataDescriptor.high = 0;
68 cdb.DataDescriptor.NodeID = dev->InitiatorNodeID;
70 cdb.NextOrb.high = cdb.NextOrb.low = 0;
71 cdb.NextOrb.reserved = NULL_POINTER;
87 ieee1394_SendCommandBlockORB(dev, &cdb);
88 ret = ieee1394_Sync();
91 XPRINTF(
"scsiRequestSense error: %d\n", ret);
97static int scsiInquiry(
struct SBP2Device *dev,
void *buffer,
int size)
102 XPRINTF(
"scsiInquiry. buffer: %p\n", buffer);
104 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));
106 cdb.DataDescriptor.low = (u32)buffer;
107 cdb.DataDescriptor.high = 0;
108 cdb.DataDescriptor.NodeID = dev->InitiatorNodeID;
110 cdb.NextOrb.high = cdb.NextOrb.low = 0;
111 cdb.NextOrb.reserved = NULL_POINTER;
127 ieee1394_SendCommandBlockORB(dev, &cdb);
128 ret = ieee1394_Sync();
131 XPRINTF(
"scsiInquiry error %d\n", ret);
135 for (i = 0; i < (
unsigned int)(size / 4); i++)
136 ((
unsigned int *)buffer)[i] = BSWAP32(((
unsigned int *)buffer)[i]);
142static int scsiStartStopUnit(
struct SBP2Device *dev)
146 XPRINTF(
"scsiStartStopUnit.\n");
148 cdb.misc = (ORB_NOTIFY | ORB_REQUEST_FORMAT(0) | CDB_MAX_PAYLOAD(dev->max_payload) | CDB_DIRECTION(WRITE_TRANSACTION) | CDB_SPEED(dev->speed));
150 cdb.DataDescriptor.low = cdb.DataDescriptor.high = 0;
151 cdb.DataDescriptor.NodeID = dev->InitiatorNodeID;
153 cdb.NextOrb.high = cdb.NextOrb.low = 0;
154 cdb.NextOrb.reserved = NULL_POINTER;
170 ieee1394_SendCommandBlockORB(dev, &cdb);
171 return (ieee1394_Sync());
174static int scsiReadCapacity(
struct SBP2Device *dev,
void *buffer,
int size)
178 XPRINTF(
"scsiReadCapacity.\n");
180 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));
182 cdb.DataDescriptor.low = (u32)buffer;
183 cdb.DataDescriptor.high = 0;
184 cdb.DataDescriptor.NodeID = dev->InitiatorNodeID;
186 cdb.NextOrb.high = cdb.NextOrb.low = 0;
187 cdb.NextOrb.reserved = NULL_POINTER;
203 ieee1394_SendCommandBlockORB(dev, &cdb);
204 return (ieee1394_Sync());
211int scsiReadSector(
struct SBP2Device *dev,
unsigned long int lba,
void *buffer,
int sectorCount)
213 unsigned int nOrbs, OrbsRemaining, i, sectorsToRead, sectorsRemaining, SectorsPerBlock, BlockNum;
214 unsigned long int startingLBA;
215 void *bufferPtr, *PreviousReqBufferPtr;
218 XPRINTF(
"scsiReadSector. buffer: %p, lba: 0x%08lx, numsectors: %d.\n", buffer, lba, sectorCount);
219 SectorsPerBlock = XFER_BLOCK_SIZE / dev->sectorSize;
220 OrbsRemaining = sectorCount / SectorsPerBlock;
221 if ((sectorCount % SectorsPerBlock) != 0)
224 XPRINTF(
"NumOrbs=%d cdb: %p.\n", OrbsRemaining, cdb);
227 sectorsRemaining = sectorCount;
231 for (PreviousReqBufferPtr = NULL, BlockNum = 0, sectorsToRead = 0; (OrbsRemaining > 0) && (result == 0); OrbsRemaining -= nOrbs, BlockNum++) {
232 nOrbs = (OrbsRemaining > MAX_ORBS) ? MAX_ORBS : OrbsRemaining;
235 for (i = 0; i < sectorsToRead << 7; i++)
236 ((
unsigned int *)PreviousReqBufferPtr)[i] = BSWAP32(((
unsigned int *)PreviousReqBufferPtr)[i]);
237 result = ieee1394_Sync();
243 PreviousReqBufferPtr = bufferPtr;
245 for (i = 0; i < nOrbs; i++) {
246 sectorsToRead = (sectorsRemaining > SectorsPerBlock) ? SectorsPerBlock : sectorsRemaining;
248 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)));
250 cdb[i].DataDescriptor.low = (u32)bufferPtr;
251 cdb[i].DataDescriptor.high = 0;
252 cdb[i].DataDescriptor.NodeID = dev->InitiatorNodeID;
255 cdb[i - 1].NextOrb.high = 0;
256 cdb[i - 1].NextOrb.low = (u32)&cdb[i];
257 cdb[i - 1].NextOrb.reserved = 0;
261 cdb[i].CDBs[3] = 0x28;
263 cdb[i].CDBs[1] = (startingLBA & 0xFF000000) >> 24;
264 cdb[i].CDBs[0] = (startingLBA & 0xFF0000) >> 16;
265 cdb[i].CDBs[7] = (startingLBA & 0xFF00) >> 8;
266 cdb[i].CDBs[6] = (startingLBA & 0xFF);
268 cdb[i].CDBs[4] = (sectorsToRead & 0xFF00) >> 8;
269 cdb[i].CDBs[11] = (sectorsToRead & 0xFF);
274 startingLBA += sectorsToRead;
275 sectorsRemaining -= sectorsToRead;
276 bufferPtr = (
void *)((u8 *)bufferPtr + (dev->sectorSize * sectorsToRead));
280 cdb[i - 1].NextOrb.high = cdb[i - 1].NextOrb.low = 0;
281 cdb[i - 1].NextOrb.reserved = NULL_POINTER;
283 ieee1394_SendCommandBlockORB(dev, cdb);
287 result = ieee1394_Sync();
288 for (i = 0; i < sectorsToRead << 7; i++)
289 ((
unsigned int *)PreviousReqBufferPtr)[i] = BSWAP32(((
unsigned int *)PreviousReqBufferPtr)[i]);
291 XPRINTF(
"scsiReadSector done.\n");
296int scsiWriteSector(
struct SBP2Device *dev,
unsigned long int lba,
void *buffer,
int sectorCount)
298 unsigned int nOrbs, OrbsRemaining, i, sectorsToRead, sectorsRemaining, SectorsPerBlock;
299 unsigned long int startingLBA;
301 int result, max_payload;
303 XPRINTF(
"scsiWriteSector.\n");
304 SectorsPerBlock = XFER_BLOCK_SIZE / dev->sectorSize;
305 OrbsRemaining = sectorCount / SectorsPerBlock;
306 if ((sectorCount % SectorsPerBlock) != 0)
310 sectorsRemaining = sectorCount;
312 max_payload = (dev->max_payload > 7) ? 7 : dev->max_payload;
315 for (; (OrbsRemaining > 0) && (result == 0); OrbsRemaining -= nOrbs) {
316 nOrbs = (OrbsRemaining > MAX_ORBS) ? MAX_ORBS : OrbsRemaining;
318 for (i = 0; i < nOrbs; i++) {
319 sectorsToRead = (sectorsRemaining > SectorsPerBlock) ? SectorsPerBlock : sectorsRemaining;
321 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)));
323 cdb[i].DataDescriptor.low = (u32)bufferPtr;
324 cdb[i].DataDescriptor.high = 0;
325 cdb[i].DataDescriptor.NodeID = dev->InitiatorNodeID;
328 cdb[i - 1].NextOrb.high = 0;
329 cdb[i - 1].NextOrb.low = (u32)&cdb[i];
330 cdb[i - 1].NextOrb.reserved = 0;
334 cdb[i].CDBs[3] = 0x2A;
336 cdb[i].CDBs[1] = (startingLBA & 0xFF000000) >> 24;
337 cdb[i].CDBs[0] = (startingLBA & 0xFF0000) >> 16;
338 cdb[i].CDBs[7] = (startingLBA & 0xFF00) >> 8;
339 cdb[i].CDBs[6] = (startingLBA & 0xFF);
341 cdb[i].CDBs[4] = (sectorsToRead & 0xFF00) >> 8;
342 cdb[i].CDBs[11] = (sectorsToRead & 0xFF);
347 startingLBA += sectorsToRead;
348 sectorsRemaining -= sectorsToRead;
349 bufferPtr = (
void *)((u8 *)bufferPtr + (dev->sectorSize * sectorsToRead));
353 cdb[i - 1].NextOrb.high = cdb[i - 1].NextOrb.low = 0;
354 cdb[i - 1].NextOrb.reserved = NULL_POINTER;
356 ieee1394_SendCommandBlockORB(dev, cdb);
357 result = ieee1394_Sync();
363static inline int InitializeSCSIDevice(
struct SBP2Device *dev)
370 XPRINTF(
"InitializeSCSIDevice.\n");
373 if ((stat = scsiInquiry(dev, &
id,
sizeof(
inquiry_data))) < 0) {
374 XPRINTF(
"Error - scsiInquiry returned %d.\n", stat);
378 printf(
"Vendor: %.8s\n",
id.vendor);
379 printf(
"Product: %.16s\n",
id.product);
380 printf(
"Revision: %.4s\n",
id.revision);
383 XPRINTF(
"Error - scsiReadCapacity %d\n", stat);
387 dev->sectorSize = rcd.block_length;
388 dev->maxLBA = rcd.last_lba;
390 printf(
"sectorSize %lu maxLBA %lu\n", dev->sectorSize, dev->maxLBA);
392 while ((stat = scsiTestUnitReady(dev)) != 0) {
393 XPRINTF(
"Error - scsiTestUnitReady %d\n", stat);
395 stat = scsiRequestSense(dev, &sd,
sizeof(
sense_data));
397 XPRINTF(
"Error - scsiRequestSense %d\n", stat);
400 if ((sd.error_code == 0x70) && (sd.sense_key != 0x00)) {
401 XPRINTF(
"Sense Data key: %02X code: %02X qual: %02X\n", sd.sense_key, sd.add_sense_code, sd.add_sense_qual);
403 if ((sd.sense_key == 0x02) && (sd.add_sense_code == 0x04) && (sd.add_sense_qual == 0x02)) {
404 XPRINTF(
"Error - Additional initalization is required for this device!\n");
405 if ((stat = scsiStartStopUnit(dev)) != 0) {
406 XPRINTF(
"Error - scsiStartStopUnit %d\n", stat);
418 part_disconnect(dev);
419 scache_kill(dev->cache);
422int ConfigureSBP2Device(
struct SBP2Device *dev)
426 if ((ret = InitializeSCSIDevice(dev)) < 0) {
427 XPRINTF(
"Error - failed to warmup device 0x%08x\n", dev->nodeID);
431 if ((dev->cache = scache_init(dev, dev->sectorSize)) == NULL) {
432 XPRINTF(
"Error - scache_init failed \n");
436 return (part_connect(dev));