SCSI de Lecture (10) et d'Écriture (10) avec le SCSI Interface Générique
J'essaie de délivrer une carte de lire(10) et write(10) à un SSD. J'utilise cet exemple de code comme une référence/base de code.
C'est mon scsi lire:
#define READ_REPLY_LEN 32
#define READ_CMDLEN 10
void scsi_read()
{
unsigned char Readbuffer[ SCSI_OFF + READ_REPLY_LEN ];
unsigned char cmdblk [ READ_CMDLEN ] =
{ 0x28, /* command */
0, /* lun/reserved */
0, /* lba */
0, /* lba */
0, /* lba */
0, /* lba */
0, /* reserved */
0, /* transfer length */
READ_REPLY_LEN, /* transfer length */
0 };/* reserved/flag/link */
memset(Readbuffer,0,sizeof(Readbuffer));
memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );
/*
* +------------------+
* | struct sg_header | <- cmd
* +------------------+
* | copy of cmdblk | <- cmd + SCSI_OFF
* +------------------+
*/
if (handle_scsi_cmd(sizeof(cmdblk), 0, cmd,
sizeof(Readbuffer) - SCSI_OFF, Readbuffer )) {
fprintf( stderr, "read failed\n" );
exit(2);
}
hex_dump(Readbuffer,sizeof(Readbuffer));
}
Et c'est mon scsi écrire:
void scsi_write ( void )
{
unsigned char Writebuffer[SCSI_OFF];
unsigned char cmdblk [] =
{ 0x2A, /* 0: command */
0, /* 1: lun/reserved */
0, /* 2: LBA */
0, /* 3: LBA */
0, /* 4: LBA */
0, /* 5: LBA */
0, /* 6: reserved */
0, /* 7: transfer length */
0, /* 8: transfer length */
0 };/* 9: control */
memset(Writebuffer,0,sizeof(Writebuffer));
memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );
cmd[SCSI_OFF+sizeof(cmdblk)+0] = 'A';
cmd[SCSI_OFF+sizeof(cmdblk)+1] = 'b';
cmd[SCSI_OFF+sizeof(cmdblk)+2] = 'c';
cmd[SCSI_OFF+sizeof(cmdblk)+3] = 'd';
cmd[SCSI_OFF+sizeof(cmdblk)+4] = 'e';
cmd[SCSI_OFF+sizeof(cmdblk)+5] = 'f';
cmd[SCSI_OFF+sizeof(cmdblk)+6] = 'g';
cmd[SCSI_OFF+sizeof(cmdblk)+7] = 0;
/*
* +------------------+
* | struct sg_header | <- cmd
* +------------------+
* | copy of cmdblk | <- cmd + SCSI_OFF
* +------------------+
* | data to write |
* +------------------+
*/
if (handle_scsi_cmd(sizeof(cmdblk), 8, cmd,
sizeof(Writebuffer) - SCSI_OFF, Writebuffer )) {
fprintf( stderr, "write failed\n" );
exit(2);
}
}
Dans l'exemple suivant, je ne
- scsi lire
- scsi écrire
- scsi lire
Et j'ai l'impression hexdumps de données qui est écrit scsi (écriture) et de ce qui est lu (scsi lire)
Read(10)
[0000] 00 00 00 44 00 00 00 44 00 00 00 00 00 00 00 00 ...D...D ........
[0010] 00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
[0020] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
[0030] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
[0040] 00 00 00 00 ....
Write(10):
[0000] 00 00 00 00 00 00 00 24 00 00 00 00 00 00 00 00 ........ ........
[0010] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
[0020] 00 00 00 00 2A 00 00 00 00 00 00 00 00 00 41 62 ........ ......Ab
[0030] 63 64 65 66 67 00 cdefg.
Read(10):
[0000] 00 00 00 44 00 00 00 44 00 00 00 00 00 00 00 00 ...D...D ........
[0010] 04 00 20 00 70 00 02 00 00 00 00 0A 00 00 00 00 ....p... ........
[0020] 04 00 00 00 41 62 63 64 65 66 67 00 00 00 00 00 ....Abcd efg.....
[0030] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
[0040] 00 00 00 00 ....
après l'exécution de trois commandes à nouveau, je dois lire Abcdefg
avec la première lecture. Droit? Mais de nouveau, rien ne change. Vous pourriez supposons maintenant, que la mémoire-je utiliser a toujours les données de la précédente funcions, mais j'obtiens le même résultat, même si je exécuter memset(Readbuff,0,sizeof(Readbuff))
avant la sys_read()
arrive.
Je suppose, que la LBA j'essaie d'écrire est peut-être interdit d'écrire, et j'ai lu le cache. Mais interating plus d'Adresses LBA de 0x00-0xFF ne change rien, cela signifie Que, j'ai lu les mêmes données (Abcdefg
).
Connaissez-vous un exemple de mise en œuvre de scsi de lecture ou d'écriture avec le scsi interface générique?
Vous devez vous connecter pour publier un commentaire.
En SCSI, les unités de la LBA et de la longueur de transfert sont dans des blocs, parfois appelés secteurs. C'est presque toujours de 512 octets. Donc, vous ne pouvez pas lire ou écrire, à seulement 32 octets. Au minimum, vous aurez à faire de 512 octets == un seul bloc. Ce seul point est la plupart de ce que vous avez besoin pour réparer.
Votre longueur de transfert est égale à zéro dans votre scsi_write mise en œuvre, il n'est donc pas, en réalité, va écrire les données.
Vous devez utiliser différents tampons de la CDB et de l'écriture/lecture de données. Je soupçonne que la confusion au sujet de ces tampons est à la tête de votre mise en œuvre d'écrire après la fin de l'un de vos statiquement les tableaux alloués et sur votre ReadBuffer. Exécuter sous valgrind et voir ce qui apparaît.
Et enfin, un lot qui pourrait aller mal dans tout ce qui est dans handle_scsi_cmd. Il peut être difficile à configurer le transfert de données... en particulier, assurez-vous que vous êtes tout droit sur la manière dont les données vont dans le I/O de l'en-tête dxfer_direction: SG_DXFER_TO_DEV pour écrire, SG_DXFER_FROM_DEV pour lire.
Découvrez cet exemple de comment faire une lecture(16). Ce n'est plus le long des lignes de ce que vous essayez d'accomplir.
https://github.com/hreinecke/sg3_utils/blob/master/examples/sg_simple16.c