aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ps3rom.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-03-08 23:44:31 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-07 13:15:45 -0400
commit944cf8b4cba42fcb284a29e4817831471adb4fad (patch)
tree4f79474f111c3aa8451e3328f5c5586a63fdbbfb /drivers/scsi/ps3rom.c
parent21a6182924d531b41cb8c24e0344213f4c90c335 (diff)
[SCSI] ps3rom: use sg buffer copy helper funcitons
Note that if scsi_bufflen(cmd) is not zero, the command always has an sg list. So this patch doesn't do the error checking in fill_from_dev_buffer and fetch_to_dev_buffer did. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Looks-OK-to: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/ps3rom.c')
-rw-r--r--drivers/scsi/ps3rom.c92
1 files changed, 10 insertions, 82 deletions
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index 0eed5ca1e032..d1e7845e11c7 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -90,76 +90,6 @@ static int ps3rom_slave_configure(struct scsi_device *scsi_dev)
90 return 0; 90 return 0;
91} 91}
92 92
93/*
94 * copy data from device into scatter/gather buffer
95 */
96static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf)
97{
98 int k, req_len, len, fin;
99 void *kaddr;
100 struct scatterlist *sgpnt;
101 unsigned int buflen;
102
103 buflen = scsi_bufflen(cmd);
104 if (!buflen)
105 return 0;
106
107 if (!scsi_sglist(cmd))
108 return -1;
109
110 req_len = fin = 0;
111 scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
112 kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
113 len = sgpnt->length;
114 if ((req_len + len) > buflen) {
115 len = buflen - req_len;
116 fin = 1;
117 }
118 memcpy(kaddr + sgpnt->offset, buf + req_len, len);
119 flush_kernel_dcache_page(sg_page(sgpnt));
120 kunmap_atomic(kaddr, KM_IRQ0);
121 req_len += len;
122 if (fin)
123 break;
124 }
125 scsi_set_resid(cmd, buflen - req_len);
126 return 0;
127}
128
129/*
130 * copy data from scatter/gather into device's buffer
131 */
132static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf)
133{
134 int k, req_len, len, fin;
135 void *kaddr;
136 struct scatterlist *sgpnt;
137 unsigned int buflen;
138
139 buflen = scsi_bufflen(cmd);
140 if (!buflen)
141 return 0;
142
143 if (!scsi_sglist(cmd))
144 return -1;
145
146 req_len = fin = 0;
147 scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
148 kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
149 len = sgpnt->length;
150 if ((req_len + len) > buflen) {
151 len = buflen - req_len;
152 fin = 1;
153 }
154 memcpy(buf + req_len, kaddr + sgpnt->offset, len);
155 kunmap_atomic(kaddr, KM_IRQ0);
156 if (fin)
157 return req_len + len;
158 req_len += sgpnt->length;
159 }
160 return req_len;
161}
162
163static int ps3rom_atapi_request(struct ps3_storage_device *dev, 93static int ps3rom_atapi_request(struct ps3_storage_device *dev,
164 struct scsi_cmnd *cmd) 94 struct scsi_cmnd *cmd)
165{ 95{
@@ -193,9 +123,7 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev,
193 else 123 else
194 atapi_cmnd.proto = PIO_DATA_OUT_PROTO; 124 atapi_cmnd.proto = PIO_DATA_OUT_PROTO;
195 atapi_cmnd.in_out = DIR_WRITE; 125 atapi_cmnd.in_out = DIR_WRITE;
196 res = fetch_to_dev_buffer(cmd, dev->bounce_buf); 126 scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
197 if (res < 0)
198 return DID_ERROR << 16;
199 break; 127 break;
200 128
201 default: 129 default:
@@ -267,9 +195,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev,
267 dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n", 195 dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n",
268 __func__, __LINE__, sectors, start_sector); 196 __func__, __LINE__, sectors, start_sector);
269 197
270 res = fetch_to_dev_buffer(cmd, dev->bounce_buf); 198 scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
271 if (res < 0)
272 return DID_ERROR << 16;
273 199
274 res = lv1_storage_write(dev->sbd.dev_id, 200 res = lv1_storage_write(dev->sbd.dev_id,
275 dev->regions[dev->region_idx].id, start_sector, 201 dev->regions[dev->region_idx].id, start_sector,
@@ -379,11 +305,13 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
379 if (!status) { 305 if (!status) {
380 /* OK, completed */ 306 /* OK, completed */
381 if (cmd->sc_data_direction == DMA_FROM_DEVICE) { 307 if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
382 res = fill_from_dev_buffer(cmd, dev->bounce_buf); 308 int len;
383 if (res) { 309
384 cmd->result = DID_ERROR << 16; 310 len = scsi_sg_copy_from_buffer(cmd,
385 goto done; 311 dev->bounce_buf,
386 } 312 dev->bounce_size);
313
314 scsi_set_resid(cmd, scsi_bufflen(cmd) - len);
387 } 315 }
388 cmd->result = DID_OK << 16; 316 cmd->result = DID_OK << 16;
389 goto done; 317 goto done;
@@ -425,7 +353,7 @@ static struct scsi_host_template ps3rom_host_template = {
425 .cmd_per_lun = 1, 353 .cmd_per_lun = 1,
426 .emulated = 1, /* only sg driver uses this */ 354 .emulated = 1, /* only sg driver uses this */
427 .max_sectors = PS3ROM_MAX_SECTORS, 355 .max_sectors = PS3ROM_MAX_SECTORS,
428 .use_clustering = DISABLE_CLUSTERING, 356 .use_clustering = ENABLE_CLUSTERING,
429 .module = THIS_MODULE, 357 .module = THIS_MODULE,
430}; 358};
431 359