[U-Boot] [PATCH 03/20] scsi: Add scsi_write to SCSI driver

Simon Glass sjg at chromium.org
Fri Oct 19 05:45:00 CEST 2012


From: Hung-Te Lin <hungte at chromium.org>

Implement write functionality in the scsi layer. A ''scsi write'
command is also added to console for testing.

Signed-off-by: Hung-Te Lin <hungte at chromium.org>
Signed-off-by: Simon Glass <sjg at chromium.org>
---
 common/cmd_scsi.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c
index 3890afd..30d8d12 100644
--- a/common/cmd_scsi.c
+++ b/common/cmd_scsi.c
@@ -82,7 +82,7 @@ void scsi_setup_inquiry(ccb * pccb);
 void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
 
 
-ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer);
+static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer);
 
 
 /*********************************************************************************
@@ -349,9 +349,10 @@ int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 #define SCSI_MAX_READ_BLK 0xFFFF /* almost the maximum amount of the scsi_ext command.. */
 
-ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer)
+static ulong scsi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
 {
-	ulong start,blks, buf_addr;
+	lbaint_t start, blks;
+	uintptr_t buf_addr;
 	unsigned short smallblks;
 	ccb* pccb=(ccb *)&tempccb;
 	device&=0xff;
@@ -362,7 +363,9 @@ ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer)
 	buf_addr=(unsigned long)buffer;
 	start=blknr;
 	blks=blkcnt;
-	debug ("\nscsi_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks,(unsigned long)buffer);
+	debug("\nscsi_read: dev %d startblk " LBAF
+	      ", blccnt " LBAF " buffer %lx\n",
+	      device, start, blks, (unsigned long)buffer);
 	do {
 		pccb->pdata=(unsigned char *)buf_addr;
 		if(blks>SCSI_MAX_READ_BLK) {
@@ -379,7 +382,9 @@ ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer)
 			start+=blks;
 			blks=0;
 		}
-		debug ("scsi_read_ext: startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
+		debug("scsi_read_ext: startblk " LBAF
+		      ", blccnt %x buffer %lx\n",
+		      start, smallblks, buf_addr);
 		if(scsi_exec(pccb)!=TRUE) {
 			scsi_print_error(pccb);
 			blkcnt-=blks;
@@ -387,10 +392,65 @@ ulong scsi_read(int device, ulong blknr, ulong blkcnt, void *buffer)
 		}
 		buf_addr+=pccb->datalen;
 	} while(blks!=0);
-	debug ("scsi_read_ext: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
+	debug("scsi_read_ext: end startblk " LBAF
+	      ", blccnt %x buffer %lx\n", start, smallblks, buf_addr);
 	return(blkcnt);
 }
 
+/*******************************************************************************
+ * scsi_write
+ */
+
+/* Almost the maximum amount of the scsi_ext command.. */
+#define SCSI_MAX_WRITE_BLK 0xFFFF
+
+static ulong scsi_write(int device, ulong blknr,
+			lbaint_t blkcnt, const void *buffer)
+{
+	lbaint_t start, blks;
+	uintptr_t buf_addr;
+	unsigned short smallblks;
+	ccb* pccb = (ccb *)&tempccb;
+	device &= 0xff;
+	/* Setup  device
+	 */
+	pccb->target = scsi_dev_desc[device].target;
+	pccb->lun = scsi_dev_desc[device].lun;
+	buf_addr = (unsigned long)buffer;
+	start = blknr;
+	blks = blkcnt;
+	debug("\n%s: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
+	      __func__, device, start, blks, (unsigned long)buffer);
+	do {
+		pccb->pdata = (unsigned char *)buf_addr;
+		if (blks > SCSI_MAX_WRITE_BLK) {
+			pccb->datalen = (scsi_dev_desc[device].blksz *
+					 SCSI_MAX_WRITE_BLK);
+			smallblks = SCSI_MAX_WRITE_BLK;
+			scsi_setup_write_ext(pccb, start, smallblks);
+			start += SCSI_MAX_WRITE_BLK;
+			blks -= SCSI_MAX_WRITE_BLK;
+		} else {
+			pccb->datalen = scsi_dev_desc[device].blksz * blks;
+			smallblks = (unsigned short)blks;
+			scsi_setup_write_ext(pccb, start, smallblks);
+			start += blks;
+			blks = 0;
+		}
+		debug("%s: startblk " LBAF ", blccnt %x buffer %lx\n",
+		      __func__, start, smallblks, buf_addr);
+		if (scsi_exec(pccb) != TRUE) {
+			scsi_print_error(pccb);
+			blkcnt -= blks;
+			break;
+		}
+		buf_addr += pccb->datalen;
+	} while (blks != 0);
+	debug("%s: end startblk " LBAF ", blccnt %x buffer %lx\n",
+	      __func__, start, smallblks, buf_addr);
+	return blkcnt;
+}
+
 /* copy src to dest, skipping leading and trailing blanks
  * and null terminate the string
  */
-- 
1.7.7.3



More information about the U-Boot mailing list