aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ps3rom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ps3rom.c')
-rw-r--r--drivers/scsi/ps3rom.c101
1 files changed, 12 insertions, 89 deletions
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index fad6cb5cba28..ce48e2d0193c 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -26,6 +26,7 @@
26#include <scsi/scsi_dbg.h> 26#include <scsi/scsi_dbg.h>
27#include <scsi/scsi_device.h> 27#include <scsi/scsi_device.h>
28#include <scsi/scsi_host.h> 28#include <scsi/scsi_host.h>
29#include <scsi/scsi_eh.h>
29 30
30#include <asm/lv1call.h> 31#include <asm/lv1call.h>
31#include <asm/ps3stor.h> 32#include <asm/ps3stor.h>
@@ -90,78 +91,6 @@ static int ps3rom_slave_configure(struct scsi_device *scsi_dev)
90 return 0; 91 return 0;
91} 92}
92 93
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, act_len, len, active;
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 active = 1;
111 req_len = act_len = 0;
112 scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
113 if (active) {
114 kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
115 len = sgpnt->length;
116 if ((req_len + len) > buflen) {
117 active = 0;
118 len = buflen - req_len;
119 }
120 memcpy(kaddr + sgpnt->offset, buf + req_len, len);
121 flush_kernel_dcache_page(sg_page(sgpnt));
122 kunmap_atomic(kaddr, KM_IRQ0);
123 act_len += len;
124 }
125 req_len += sgpnt->length;
126 }
127 scsi_set_resid(cmd, buflen - act_len);
128 return 0;
129}
130
131/*
132 * copy data from scatter/gather into device's buffer
133 */
134static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf)
135{
136 int k, req_len, len, fin;
137 void *kaddr;
138 struct scatterlist *sgpnt;
139 unsigned int buflen;
140
141 buflen = scsi_bufflen(cmd);
142 if (!buflen)
143 return 0;
144
145 if (!scsi_sglist(cmd))
146 return -1;
147
148 req_len = fin = 0;
149 scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
150 kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
151 len = sgpnt->length;
152 if ((req_len + len) > buflen) {
153 len = buflen - req_len;
154 fin = 1;
155 }
156 memcpy(buf + req_len, kaddr + sgpnt->offset, len);
157 kunmap_atomic(kaddr, KM_IRQ0);
158 if (fin)
159 return req_len + len;
160 req_len += sgpnt->length;
161 }
162 return req_len;
163}
164
165static int ps3rom_atapi_request(struct ps3_storage_device *dev, 94static int ps3rom_atapi_request(struct ps3_storage_device *dev,
166 struct scsi_cmnd *cmd) 95 struct scsi_cmnd *cmd)
167{ 96{
@@ -195,9 +124,7 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev,
195 else 124 else
196 atapi_cmnd.proto = PIO_DATA_OUT_PROTO; 125 atapi_cmnd.proto = PIO_DATA_OUT_PROTO;
197 atapi_cmnd.in_out = DIR_WRITE; 126 atapi_cmnd.in_out = DIR_WRITE;
198 res = fetch_to_dev_buffer(cmd, dev->bounce_buf); 127 scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
199 if (res < 0)
200 return DID_ERROR << 16;
201 break; 128 break;
202 129
203 default: 130 default:
@@ -269,9 +196,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev,
269 dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n", 196 dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n",
270 __func__, __LINE__, sectors, start_sector); 197 __func__, __LINE__, sectors, start_sector);
271 198
272 res = fetch_to_dev_buffer(cmd, dev->bounce_buf); 199 scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
273 if (res < 0)
274 return DID_ERROR << 16;
275 200
276 res = lv1_storage_write(dev->sbd.dev_id, 201 res = lv1_storage_write(dev->sbd.dev_id,
277 dev->regions[dev->region_idx].id, start_sector, 202 dev->regions[dev->region_idx].id, start_sector,
@@ -381,11 +306,13 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
381 if (!status) { 306 if (!status) {
382 /* OK, completed */ 307 /* OK, completed */
383 if (cmd->sc_data_direction == DMA_FROM_DEVICE) { 308 if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
384 res = fill_from_dev_buffer(cmd, dev->bounce_buf); 309 int len;
385 if (res) { 310
386 cmd->result = DID_ERROR << 16; 311 len = scsi_sg_copy_from_buffer(cmd,
387 goto done; 312 dev->bounce_buf,
388 } 313 dev->bounce_size);
314
315 scsi_set_resid(cmd, scsi_bufflen(cmd) - len);
389 } 316 }
390 cmd->result = DID_OK << 16; 317 cmd->result = DID_OK << 16;
391 goto done; 318 goto done;
@@ -404,11 +331,7 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
404 goto done; 331 goto done;
405 } 332 }
406 333
407 cmd->sense_buffer[0] = 0x70; 334 scsi_build_sense_buffer(0, cmd->sense_buffer, sense_key, asc, ascq);
408 cmd->sense_buffer[2] = sense_key;
409 cmd->sense_buffer[7] = 16 - 6;
410 cmd->sense_buffer[12] = asc;
411 cmd->sense_buffer[13] = ascq;
412 cmd->result = SAM_STAT_CHECK_CONDITION; 335 cmd->result = SAM_STAT_CHECK_CONDITION;
413 336
414done: 337done:
@@ -427,7 +350,7 @@ static struct scsi_host_template ps3rom_host_template = {
427 .cmd_per_lun = 1, 350 .cmd_per_lun = 1,
428 .emulated = 1, /* only sg driver uses this */ 351 .emulated = 1, /* only sg driver uses this */
429 .max_sectors = PS3ROM_MAX_SECTORS, 352 .max_sectors = PS3ROM_MAX_SECTORS,
430 .use_clustering = DISABLE_CLUSTERING, 353 .use_clustering = ENABLE_CLUSTERING,
431 .module = THIS_MODULE, 354 .module = THIS_MODULE,
432}; 355};
433 356