diff options
Diffstat (limited to 'drivers/scsi/ps3rom.c')
-rw-r--r-- | drivers/scsi/ps3rom.c | 92 |
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 | */ | ||
96 | static 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 | */ | ||
132 | static 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 | |||
163 | static int ps3rom_atapi_request(struct ps3_storage_device *dev, | 93 | static 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 | ||