aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/advansys.c88
1 files changed, 39 insertions, 49 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 3dd785617602..fd4d6695fea9 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -380,7 +380,7 @@ typedef struct asc_sg_head {
380 ushort queue_cnt; 380 ushort queue_cnt;
381 ushort entry_to_copy; 381 ushort entry_to_copy;
382 ushort res; 382 ushort res;
383 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST]; 383 ASC_SG_LIST sg_list[0];
384} ASC_SG_HEAD; 384} ASC_SG_HEAD;
385 385
386typedef struct asc_scsi_q { 386typedef struct asc_scsi_q {
@@ -2559,12 +2559,6 @@ static int asc_board_count;
2559/* Overrun buffer used by all narrow boards. */ 2559/* Overrun buffer used by all narrow boards. */
2560static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; 2560static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
2561 2561
2562/*
2563 * Global structures required to issue a command.
2564 */
2565static ASC_SCSI_Q asc_scsi_q = { {0} };
2566static ASC_SG_HEAD asc_sg_head = { 0 };
2567
2568#ifdef ADVANSYS_DEBUG 2562#ifdef ADVANSYS_DEBUG
2569static int asc_dbglvl = 3; 2563static int asc_dbglvl = 3;
2570 2564
@@ -10192,39 +10186,28 @@ static int advansys_slave_configure(struct scsi_device *sdev)
10192 return 0; 10186 return 0;
10193} 10187}
10194 10188
10195/* 10189static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
10196 * Build a request structure for the Asc Library (Narrow Board). 10190 struct asc_scsi_q *asc_scsi_q)
10197 *
10198 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
10199 * used to build the request.
10200 *
10201 * If an error occurs, then return ASC_ERROR.
10202 */
10203static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
10204{ 10191{
10205 /* 10192 memset(asc_scsi_q, 0, sizeof(*asc_scsi_q));
10206 * Mutually exclusive access is required to 'asc_scsi_q' and
10207 * 'asc_sg_head' until after the request is started.
10208 */
10209 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
10210 10193
10211 /* 10194 /*
10212 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'. 10195 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
10213 */ 10196 */
10214 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp); 10197 asc_scsi_q->q2.srb_ptr = ASC_VADDR_TO_U32(scp);
10215 10198
10216 /* 10199 /*
10217 * Build the ASC_SCSI_Q request. 10200 * Build the ASC_SCSI_Q request.
10218 */ 10201 */
10219 asc_scsi_q.cdbptr = &scp->cmnd[0]; 10202 asc_scsi_q->cdbptr = &scp->cmnd[0];
10220 asc_scsi_q.q2.cdb_len = scp->cmd_len; 10203 asc_scsi_q->q2.cdb_len = scp->cmd_len;
10221 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); 10204 asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
10222 asc_scsi_q.q1.target_lun = scp->device->lun; 10205 asc_scsi_q->q1.target_lun = scp->device->lun;
10223 asc_scsi_q.q2.target_ix = 10206 asc_scsi_q->q2.target_ix =
10224 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); 10207 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
10225 asc_scsi_q.q1.sense_addr = 10208 asc_scsi_q->q1.sense_addr =
10226 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); 10209 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
10227 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer); 10210 asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer);
10228 10211
10229 /* 10212 /*
10230 * If there are any outstanding requests for the current target, 10213 * If there are any outstanding requests for the current target,
@@ -10239,9 +10222,9 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
10239 */ 10222 */
10240 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && 10223 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
10241 (boardp->reqcnt[scp->device->id] % 255) == 0) { 10224 (boardp->reqcnt[scp->device->id] % 255) == 0) {
10242 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG; 10225 asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG;
10243 } else { 10226 } else {
10244 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG; 10227 asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG;
10245 } 10228 }
10246 10229
10247 /* 10230 /*
@@ -10257,12 +10240,12 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
10257 dma_map_single(boardp->dev, scp->request_buffer, 10240 dma_map_single(boardp->dev, scp->request_buffer,
10258 scp->request_bufflen, 10241 scp->request_bufflen,
10259 scp->sc_data_direction) : 0; 10242 scp->sc_data_direction) : 0;
10260 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); 10243 asc_scsi_q->q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
10261 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen); 10244 asc_scsi_q->q1.data_cnt = cpu_to_le32(scp->request_bufflen);
10262 ASC_STATS_ADD(scp->device->host, cont_xfer, 10245 ASC_STATS_ADD(scp->device->host, cont_xfer,
10263 ASC_CEILING(scp->request_bufflen, 512)); 10246 ASC_CEILING(scp->request_bufflen, 512));
10264 asc_scsi_q.q1.sg_queue_cnt = 0; 10247 asc_scsi_q->q1.sg_queue_cnt = 0;
10265 asc_scsi_q.sg_head = NULL; 10248 asc_scsi_q->sg_head = NULL;
10266 } else { 10249 } else {
10267 /* 10250 /*
10268 * CDB scatter-gather request list. 10251 * CDB scatter-gather request list.
@@ -10270,6 +10253,7 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
10270 int sgcnt; 10253 int sgcnt;
10271 int use_sg; 10254 int use_sg;
10272 struct scatterlist *slp; 10255 struct scatterlist *slp;
10256 struct asc_sg_head *asc_sg_head;
10273 10257
10274 slp = (struct scatterlist *)scp->request_buffer; 10258 slp = (struct scatterlist *)scp->request_buffer;
10275 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg, 10259 use_sg = dma_map_sg(boardp->dev, slp, scp->use_sg,
@@ -10287,28 +10271,31 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
10287 10271
10288 ASC_STATS(scp->device->host, sg_cnt); 10272 ASC_STATS(scp->device->host, sg_cnt);
10289 10273
10290 /* 10274 asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) +
10291 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q 10275 use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC);
10292 * structure to point to it. 10276 if (!asc_sg_head) {
10293 */ 10277 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
10294 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD)); 10278 scp->sc_data_direction);
10279 scp->result = HOST_BYTE(DID_SOFT_ERROR);
10280 return ASC_ERROR;
10281 }
10295 10282
10296 asc_scsi_q.q1.cntl |= QC_SG_HEAD; 10283 asc_scsi_q->q1.cntl |= QC_SG_HEAD;
10297 asc_scsi_q.sg_head = &asc_sg_head; 10284 asc_scsi_q->sg_head = asc_sg_head;
10298 asc_scsi_q.q1.data_cnt = 0; 10285 asc_scsi_q->q1.data_cnt = 0;
10299 asc_scsi_q.q1.data_addr = 0; 10286 asc_scsi_q->q1.data_addr = 0;
10300 /* This is a byte value, otherwise it would need to be swapped. */ 10287 /* This is a byte value, otherwise it would need to be swapped. */
10301 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg; 10288 asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg;
10302 ASC_STATS_ADD(scp->device->host, sg_elem, 10289 ASC_STATS_ADD(scp->device->host, sg_elem,
10303 asc_sg_head.entry_cnt); 10290 asc_sg_head->entry_cnt);
10304 10291
10305 /* 10292 /*
10306 * Convert scatter-gather list into ASC_SG_HEAD list. 10293 * Convert scatter-gather list into ASC_SG_HEAD list.
10307 */ 10294 */
10308 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) { 10295 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
10309 asc_sg_head.sg_list[sgcnt].addr = 10296 asc_sg_head->sg_list[sgcnt].addr =
10310 cpu_to_le32(sg_dma_address(slp)); 10297 cpu_to_le32(sg_dma_address(slp));
10311 asc_sg_head.sg_list[sgcnt].bytes = 10298 asc_sg_head->sg_list[sgcnt].bytes =
10312 cpu_to_le32(sg_dma_len(slp)); 10299 cpu_to_le32(sg_dma_len(slp));
10313 ASC_STATS_ADD(scp->device->host, sg_xfer, 10300 ASC_STATS_ADD(scp->device->host, sg_xfer,
10314 ASC_CEILING(sg_dma_len(slp), 512)); 10301 ASC_CEILING(sg_dma_len(slp), 512));
@@ -11338,14 +11325,17 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
11338 11325
11339 if (ASC_NARROW_BOARD(boardp)) { 11326 if (ASC_NARROW_BOARD(boardp)) {
11340 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; 11327 ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
11328 struct asc_scsi_q asc_scsi_q;
11341 11329
11342 /* asc_build_req() can not return ASC_BUSY. */ 11330 /* asc_build_req() can not return ASC_BUSY. */
11343 if (asc_build_req(boardp, scp) == ASC_ERROR) { 11331 ret = asc_build_req(boardp, scp, &asc_scsi_q);
11332 if (ret == ASC_ERROR) {
11344 ASC_STATS(scp->device->host, build_error); 11333 ASC_STATS(scp->device->host, build_error);
11345 return ASC_ERROR; 11334 return ASC_ERROR;
11346 } 11335 }
11347 11336
11348 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q); 11337 ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q);
11338 kfree(asc_scsi_q.sg_head);
11349 err_code = asc_dvc->err_code; 11339 err_code = asc_dvc->err_code;
11350 } else { 11340 } else {
11351 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var; 11341 ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var;