aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/hp/sim/simscsi.c66
1 files changed, 15 insertions, 51 deletions
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index 64248b58f63f..e62694f8ef75 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -122,48 +122,22 @@ simscsi_biosparam (struct scsi_device *sdev, struct block_device *n,
122} 122}
123 123
124static void 124static void
125simscsi_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset, unsigned long len)
126{
127 struct disk_stat stat;
128 struct disk_req req;
129
130 req.addr = __pa(sc->request_buffer);
131 req.len = len; /* # of bytes to transfer */
132
133 if (sc->request_bufflen < req.len)
134 return;
135
136 stat.fd = desc[sc->device->id];
137 if (DBG)
138 printk("simscsi_%s @ %lx (off %lx)\n",
139 mode == SSC_READ ? "read":"write", req.addr, offset);
140 ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
141 ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
142
143 if (stat.count == req.len) {
144 sc->result = GOOD;
145 } else {
146 sc->result = DID_ERROR << 16;
147 }
148}
149
150static void
151simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset) 125simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
152{ 126{
153 int list_len = sc->use_sg; 127 int i;
154 struct scatterlist *sl = (struct scatterlist *)sc->request_buffer; 128 struct scatterlist *sl;
155 struct disk_stat stat; 129 struct disk_stat stat;
156 struct disk_req req; 130 struct disk_req req;
157 131
158 stat.fd = desc[sc->device->id]; 132 stat.fd = desc[sc->device->id];
159 133
160 while (list_len) { 134 scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
161 req.addr = __pa(page_address(sl->page) + sl->offset); 135 req.addr = __pa(page_address(sl->page) + sl->offset);
162 req.len = sl->length; 136 req.len = sl->length;
163 if (DBG) 137 if (DBG)
164 printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n", 138 printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
165 mode == SSC_READ ? "read":"write", req.addr, offset, 139 mode == SSC_READ ? "read":"write", req.addr, offset,
166 list_len, sl->length); 140 scsi_sg_count(sc) - i, sl->length);
167 ia64_ssc(stat.fd, 1, __pa(&req), offset, mode); 141 ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
168 ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION); 142 ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
169 143
@@ -173,8 +147,6 @@ simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
173 return; 147 return;
174 } 148 }
175 offset += sl->length; 149 offset += sl->length;
176 sl++;
177 list_len--;
178 } 150 }
179 sc->result = GOOD; 151 sc->result = GOOD;
180} 152}
@@ -190,10 +162,7 @@ simscsi_readwrite6 (struct scsi_cmnd *sc, int mode)
190 unsigned long offset; 162 unsigned long offset;
191 163
192 offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512; 164 offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512;
193 if (sc->use_sg > 0) 165 simscsi_sg_readwrite(sc, mode, offset);
194 simscsi_sg_readwrite(sc, mode, offset);
195 else
196 simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512);
197} 166}
198 167
199static size_t 168static size_t
@@ -230,26 +199,21 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
230 | ((unsigned long)sc->cmnd[3] << 16) 199 | ((unsigned long)sc->cmnd[3] << 16)
231 | ((unsigned long)sc->cmnd[4] << 8) 200 | ((unsigned long)sc->cmnd[4] << 8)
232 | ((unsigned long)sc->cmnd[5] << 0))*512UL; 201 | ((unsigned long)sc->cmnd[5] << 0))*512UL;
233 if (sc->use_sg > 0) 202 simscsi_sg_readwrite(sc, mode, offset);
234 simscsi_sg_readwrite(sc, mode, offset);
235 else
236 simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
237} 203}
238 204
239static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len) 205static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
240{ 206{
241 207
242 int scatterlen = sc->use_sg; 208 int i;
209 unsigned thislen;
243 struct scatterlist *slp; 210 struct scatterlist *slp;
244 211
245 if (scatterlen == 0) 212 scsi_for_each_sg(sc, slp, scsi_sg_count(sc), i) {
246 memcpy(sc->request_buffer, buf, len); 213 if (!len)
247 else for (slp = (struct scatterlist *)sc->request_buffer; 214 break;
248 scatterlen-- > 0 && len > 0; slp++) { 215 thislen = min(len, slp->length);
249 unsigned thislen = min(len, slp->length);
250
251 memcpy(page_address(slp->page) + slp->offset, buf, thislen); 216 memcpy(page_address(slp->page) + slp->offset, buf, thislen);
252 slp++;
253 len -= thislen; 217 len -= thislen;
254 } 218 }
255} 219}
@@ -275,7 +239,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
275 if (target_id <= 15 && sc->device->lun == 0) { 239 if (target_id <= 15 && sc->device->lun == 0) {
276 switch (sc->cmnd[0]) { 240 switch (sc->cmnd[0]) {
277 case INQUIRY: 241 case INQUIRY:
278 if (sc->request_bufflen < 35) { 242 if (scsi_bufflen(sc) < 35) {
279 break; 243 break;
280 } 244 }
281 sprintf (fname, "%s%c", simscsi_root, 'a' + target_id); 245 sprintf (fname, "%s%c", simscsi_root, 'a' + target_id);
@@ -328,7 +292,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
328 break; 292 break;
329 293
330 case READ_CAPACITY: 294 case READ_CAPACITY:
331 if (desc[target_id] < 0 || sc->request_bufflen < 8) { 295 if (desc[target_id] < 0 || scsi_bufflen(sc) < 8) {
332 break; 296 break;
333 } 297 }
334 buf = localbuf; 298 buf = localbuf;
@@ -350,7 +314,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
350 case MODE_SENSE: 314 case MODE_SENSE:
351 case MODE_SENSE_10: 315 case MODE_SENSE_10:
352 /* sd.c uses this to determine whether disk does write-caching. */ 316 /* sd.c uses this to determine whether disk does write-caching. */
353 simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen); 317 simscsi_fillresult(sc, (char *)empty_zero_page, scsi_bufflen(sc));
354 sc->result = GOOD; 318 sc->result = GOOD;
355 break; 319 break;
356 320