diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 80 |
1 files changed, 23 insertions, 57 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index cb73faa7241d..5870866abc99 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -350,20 +350,19 @@ static void unmap_cmd_data(struct srp_cmd *cmd, | |||
350 | } | 350 | } |
351 | } | 351 | } |
352 | 352 | ||
353 | static int map_sg_list(int num_entries, | 353 | static int map_sg_list(struct scsi_cmnd *cmd, int nseg, |
354 | struct scatterlist *sg, | ||
355 | struct srp_direct_buf *md) | 354 | struct srp_direct_buf *md) |
356 | { | 355 | { |
357 | int i; | 356 | int i; |
357 | struct scatterlist *sg; | ||
358 | u64 total_length = 0; | 358 | u64 total_length = 0; |
359 | 359 | ||
360 | for (i = 0; i < num_entries; ++i) { | 360 | scsi_for_each_sg(cmd, sg, nseg, i) { |
361 | struct srp_direct_buf *descr = md + i; | 361 | struct srp_direct_buf *descr = md + i; |
362 | struct scatterlist *sg_entry = &sg[i]; | 362 | descr->va = sg_dma_address(sg); |
363 | descr->va = sg_dma_address(sg_entry); | 363 | descr->len = sg_dma_len(sg); |
364 | descr->len = sg_dma_len(sg_entry); | ||
365 | descr->key = 0; | 364 | descr->key = 0; |
366 | total_length += sg_dma_len(sg_entry); | 365 | total_length += sg_dma_len(sg); |
367 | } | 366 | } |
368 | return total_length; | 367 | return total_length; |
369 | } | 368 | } |
@@ -384,24 +383,28 @@ static int map_sg_data(struct scsi_cmnd *cmd, | |||
384 | 383 | ||
385 | int sg_mapped; | 384 | int sg_mapped; |
386 | u64 total_length = 0; | 385 | u64 total_length = 0; |
387 | struct scatterlist *sg = cmd->request_buffer; | ||
388 | struct srp_direct_buf *data = | 386 | struct srp_direct_buf *data = |
389 | (struct srp_direct_buf *) srp_cmd->add_data; | 387 | (struct srp_direct_buf *) srp_cmd->add_data; |
390 | struct srp_indirect_buf *indirect = | 388 | struct srp_indirect_buf *indirect = |
391 | (struct srp_indirect_buf *) data; | 389 | (struct srp_indirect_buf *) data; |
392 | 390 | ||
393 | sg_mapped = dma_map_sg(dev, sg, cmd->use_sg, DMA_BIDIRECTIONAL); | 391 | sg_mapped = scsi_dma_map(cmd); |
394 | 392 | if (!sg_mapped) | |
395 | if (sg_mapped == 0) | 393 | return 1; |
394 | else if (sg_mapped < 0) | ||
396 | return 0; | 395 | return 0; |
396 | else if (sg_mapped > SG_ALL) { | ||
397 | printk(KERN_ERR | ||
398 | "ibmvscsi: More than %d mapped sg entries, got %d\n", | ||
399 | SG_ALL, sg_mapped); | ||
400 | return 0; | ||
401 | } | ||
397 | 402 | ||
398 | set_srp_direction(cmd, srp_cmd, sg_mapped); | 403 | set_srp_direction(cmd, srp_cmd, sg_mapped); |
399 | 404 | ||
400 | /* special case; we can use a single direct descriptor */ | 405 | /* special case; we can use a single direct descriptor */ |
401 | if (sg_mapped == 1) { | 406 | if (sg_mapped == 1) { |
402 | data->va = sg_dma_address(&sg[0]); | 407 | map_sg_list(cmd, sg_mapped, data); |
403 | data->len = sg_dma_len(&sg[0]); | ||
404 | data->key = 0; | ||
405 | return 1; | 408 | return 1; |
406 | } | 409 | } |
407 | 410 | ||
@@ -410,7 +413,7 @@ static int map_sg_data(struct scsi_cmnd *cmd, | |||
410 | indirect->table_desc.key = 0; | 413 | indirect->table_desc.key = 0; |
411 | 414 | ||
412 | if (sg_mapped <= MAX_INDIRECT_BUFS) { | 415 | if (sg_mapped <= MAX_INDIRECT_BUFS) { |
413 | total_length = map_sg_list(sg_mapped, sg, | 416 | total_length = map_sg_list(cmd, sg_mapped, |
414 | &indirect->desc_list[0]); | 417 | &indirect->desc_list[0]); |
415 | indirect->len = total_length; | 418 | indirect->len = total_length; |
416 | return 1; | 419 | return 1; |
@@ -419,7 +422,7 @@ static int map_sg_data(struct scsi_cmnd *cmd, | |||
419 | /* get indirect table */ | 422 | /* get indirect table */ |
420 | if (!evt_struct->ext_list) { | 423 | if (!evt_struct->ext_list) { |
421 | evt_struct->ext_list = (struct srp_direct_buf *) | 424 | evt_struct->ext_list = (struct srp_direct_buf *) |
422 | dma_alloc_coherent(dev, | 425 | dma_alloc_coherent(dev, |
423 | SG_ALL * sizeof(struct srp_direct_buf), | 426 | SG_ALL * sizeof(struct srp_direct_buf), |
424 | &evt_struct->ext_list_token, 0); | 427 | &evt_struct->ext_list_token, 0); |
425 | if (!evt_struct->ext_list) { | 428 | if (!evt_struct->ext_list) { |
@@ -429,50 +432,17 @@ static int map_sg_data(struct scsi_cmnd *cmd, | |||
429 | } | 432 | } |
430 | } | 433 | } |
431 | 434 | ||
432 | total_length = map_sg_list(sg_mapped, sg, evt_struct->ext_list); | 435 | total_length = map_sg_list(cmd, sg_mapped, evt_struct->ext_list); |
433 | 436 | ||
434 | indirect->len = total_length; | 437 | indirect->len = total_length; |
435 | indirect->table_desc.va = evt_struct->ext_list_token; | 438 | indirect->table_desc.va = evt_struct->ext_list_token; |
436 | indirect->table_desc.len = sg_mapped * sizeof(indirect->desc_list[0]); | 439 | indirect->table_desc.len = sg_mapped * sizeof(indirect->desc_list[0]); |
437 | memcpy(indirect->desc_list, evt_struct->ext_list, | 440 | memcpy(indirect->desc_list, evt_struct->ext_list, |
438 | MAX_INDIRECT_BUFS * sizeof(struct srp_direct_buf)); | 441 | MAX_INDIRECT_BUFS * sizeof(struct srp_direct_buf)); |
439 | |||
440 | return 1; | 442 | return 1; |
441 | } | 443 | } |
442 | 444 | ||
443 | /** | 445 | /** |
444 | * map_single_data: - Maps memory and initializes memory decriptor fields | ||
445 | * @cmd: struct scsi_cmnd with the memory to be mapped | ||
446 | * @srp_cmd: srp_cmd that contains the memory descriptor | ||
447 | * @dev: device for which to map dma memory | ||
448 | * | ||
449 | * Called by map_data_for_srp_cmd() when building srp cmd from scsi cmd. | ||
450 | * Returns 1 on success. | ||
451 | */ | ||
452 | static int map_single_data(struct scsi_cmnd *cmd, | ||
453 | struct srp_cmd *srp_cmd, struct device *dev) | ||
454 | { | ||
455 | struct srp_direct_buf *data = | ||
456 | (struct srp_direct_buf *) srp_cmd->add_data; | ||
457 | |||
458 | data->va = | ||
459 | dma_map_single(dev, cmd->request_buffer, | ||
460 | cmd->request_bufflen, | ||
461 | DMA_BIDIRECTIONAL); | ||
462 | if (dma_mapping_error(data->va)) { | ||
463 | sdev_printk(KERN_ERR, cmd->device, | ||
464 | "Unable to map request_buffer for command!\n"); | ||
465 | return 0; | ||
466 | } | ||
467 | data->len = cmd->request_bufflen; | ||
468 | data->key = 0; | ||
469 | |||
470 | set_srp_direction(cmd, srp_cmd, 1); | ||
471 | |||
472 | return 1; | ||
473 | } | ||
474 | |||
475 | /** | ||
476 | * map_data_for_srp_cmd: - Calls functions to map data for srp cmds | 446 | * map_data_for_srp_cmd: - Calls functions to map data for srp cmds |
477 | * @cmd: struct scsi_cmnd with the memory to be mapped | 447 | * @cmd: struct scsi_cmnd with the memory to be mapped |
478 | * @srp_cmd: srp_cmd that contains the memory descriptor | 448 | * @srp_cmd: srp_cmd that contains the memory descriptor |
@@ -502,11 +472,7 @@ static int map_data_for_srp_cmd(struct scsi_cmnd *cmd, | |||
502 | return 0; | 472 | return 0; |
503 | } | 473 | } |
504 | 474 | ||
505 | if (!cmd->request_buffer) | 475 | return map_sg_data(cmd, evt_struct, srp_cmd, dev); |
506 | return 1; | ||
507 | if (cmd->use_sg) | ||
508 | return map_sg_data(cmd, evt_struct, srp_cmd, dev); | ||
509 | return map_single_data(cmd, srp_cmd, dev); | ||
510 | } | 476 | } |
511 | 477 | ||
512 | /** | 478 | /** |
@@ -712,9 +678,9 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct) | |||
712 | evt_struct->hostdata->dev); | 678 | evt_struct->hostdata->dev); |
713 | 679 | ||
714 | if (rsp->flags & SRP_RSP_FLAG_DOOVER) | 680 | if (rsp->flags & SRP_RSP_FLAG_DOOVER) |
715 | cmnd->resid = rsp->data_out_res_cnt; | 681 | scsi_set_resid(cmnd, rsp->data_out_res_cnt); |
716 | else if (rsp->flags & SRP_RSP_FLAG_DIOVER) | 682 | else if (rsp->flags & SRP_RSP_FLAG_DIOVER) |
717 | cmnd->resid = rsp->data_in_res_cnt; | 683 | scsi_set_resid(cmnd, rsp->data_in_res_cnt); |
718 | } | 684 | } |
719 | 685 | ||
720 | if (evt_struct->cmnd_done) | 686 | if (evt_struct->cmnd_done) |