Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 13929
b: refs/heads/master
c: 12baa42
h: refs/heads/master
i:
  13927: de51e55
v: v3
  • Loading branch information
brking@us.ibm.com authored and James Bottomley committed Nov 6, 2005
1 parent 75eb949 commit d9e2f6f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 50 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0bc42e35c74c0baab414cf623d6fe1e94cee4ca3
refs/heads/master: 12baa4202d74d799f4f8a4bd0455b485e4f8e876
104 changes: 55 additions & 49 deletions trunk/drivers/scsi/ipr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2351,31 +2351,24 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
}

/**
* ipr_map_ucode_buffer - Map a microcode download buffer
* ipr_build_ucode_ioadl - Build a microcode download IOADL
* @ipr_cmd: ipr command struct
* @sglist: scatter/gather list
* @len: total length of download buffer
*
* Maps a microcode download scatter/gather list for DMA and
* builds the IOADL.
* Builds a microcode download IOA data list (IOADL).
*
* Return value:
* 0 on success / -EIO on failure
**/
static int ipr_map_ucode_buffer(struct ipr_cmnd *ipr_cmd,
struct ipr_sglist *sglist, int len)
static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd,
struct ipr_sglist *sglist)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
struct scatterlist *scatterlist = sglist->scatterlist;
int i;

ipr_cmd->dma_use_sg = pci_map_sg(ioa_cfg->pdev, scatterlist,
sglist->num_sg, DMA_TO_DEVICE);

ipr_cmd->dma_use_sg = sglist->num_dma_sg;
ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
ioarcb->write_data_transfer_length = cpu_to_be32(len);
ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len);
ioarcb->write_ioadl_len =
cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);

Expand All @@ -2386,15 +2379,52 @@ static int ipr_map_ucode_buffer(struct ipr_cmnd *ipr_cmd,
cpu_to_be32(sg_dma_address(&scatterlist[i]));
}

if (likely(ipr_cmd->dma_use_sg)) {
ioadl[i-1].flags_and_data_len |=
cpu_to_be32(IPR_IOADL_FLAGS_LAST);
ioadl[i-1].flags_and_data_len |=
cpu_to_be32(IPR_IOADL_FLAGS_LAST);
}

/**
* ipr_update_ioa_ucode - Update IOA's microcode
* @ioa_cfg: ioa config struct
* @sglist: scatter/gather list
*
* Initiate an adapter reset to update the IOA's microcode
*
* Return value:
* 0 on success / -EIO on failure
**/
static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg,
struct ipr_sglist *sglist)
{
unsigned long lock_flags;

spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);

if (ioa_cfg->ucode_sglist) {
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
dev_err(&ioa_cfg->pdev->dev,
"Microcode download already in progress\n");
return -EIO;
}
else {
dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");

sglist->num_dma_sg = pci_map_sg(ioa_cfg->pdev, sglist->scatterlist,
sglist->num_sg, DMA_TO_DEVICE);

if (!sglist->num_dma_sg) {
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
dev_err(&ioa_cfg->pdev->dev,
"Failed to map microcode download buffer!\n");
return -EIO;
}

ioa_cfg->ucode_sglist = sglist;
ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);

spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
ioa_cfg->ucode_sglist = NULL;
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
return 0;
}

Expand All @@ -2417,7 +2447,6 @@ static ssize_t ipr_store_update_fw(struct class_device *class_dev,
struct ipr_ucode_image_header *image_hdr;
const struct firmware *fw_entry;
struct ipr_sglist *sglist;
unsigned long lock_flags;
char fname[100];
char *src;
int len, result, dnld_size;
Expand Down Expand Up @@ -2458,35 +2487,17 @@ static ssize_t ipr_store_update_fw(struct class_device *class_dev,
if (result) {
dev_err(&ioa_cfg->pdev->dev,
"Microcode buffer copy to DMA buffer failed\n");
ipr_free_ucode_buffer(sglist);
release_firmware(fw_entry);
return result;
}

spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);

if (ioa_cfg->ucode_sglist) {
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
dev_err(&ioa_cfg->pdev->dev,
"Microcode download already in progress\n");
ipr_free_ucode_buffer(sglist);
release_firmware(fw_entry);
return -EIO;
goto out;
}

ioa_cfg->ucode_sglist = sglist;
ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);

spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
ioa_cfg->ucode_sglist = NULL;
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
result = ipr_update_ioa_ucode(ioa_cfg, sglist);

if (!result)
result = count;
out:
ipr_free_ucode_buffer(sglist);
release_firmware(fw_entry);

return count;
return result;
}

static struct class_device_attribute ipr_update_fw_attr = {
Expand Down Expand Up @@ -5291,12 +5302,7 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd)
ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8;
ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff;

if (ipr_map_ucode_buffer(ipr_cmd, sglist, sglist->buffer_len)) {
dev_err(&ioa_cfg->pdev->dev,
"Failed to map microcode download buffer\n");
return IPR_RC_JOB_CONTINUE;
}

ipr_build_ucode_ioadl(ipr_cmd, sglist);
ipr_cmd->job_step = ipr_reset_ucode_download_done;

ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout,
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/scsi/ipr.h
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,7 @@ struct ipr_trace_entry {
struct ipr_sglist {
u32 order;
u32 num_sg;
u32 num_dma_sg;
u32 buffer_len;
struct scatterlist scatterlist[1];
};
Expand Down

0 comments on commit d9e2f6f

Please sign in to comment.