Loading drivers/ieee1394/sbp2.c +59 −35 Original line number Diff line number Diff line Loading @@ -526,26 +526,41 @@ static void sbp2util_write_doorbell(struct work_struct *work) static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu) { struct sbp2_fwhost_info *hi = lu->hi; struct sbp2_command_info *cmd; struct device *dmadev = lu->hi->host->device.parent; int i, orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS; for (i = 0; i < orbs; i++) { cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; cmd->command_orb_dma = dma_map_single(hi->host->device.parent, &cmd->command_orb, goto failed_alloc; cmd->command_orb_dma = dma_map_single(dmadev, &cmd->command_orb, sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); cmd->sge_dma = dma_map_single(hi->host->device.parent, &cmd->scatter_gather_element, if (dma_mapping_error(dmadev, cmd->command_orb_dma)) goto failed_orb; cmd->sge_dma = dma_map_single(dmadev, &cmd->scatter_gather_element, sizeof(cmd->scatter_gather_element), DMA_TO_DEVICE); if (dma_mapping_error(dmadev, cmd->sge_dma)) goto failed_sge; INIT_LIST_HEAD(&cmd->list); list_add_tail(&cmd->list, &lu->cmd_orb_completed); } return 0; failed_sge: dma_unmap_single(dmadev, cmd->command_orb_dma, sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); failed_orb: kfree(cmd); failed_alloc: return -ENOMEM; } static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu, Loading Loading @@ -1494,7 +1509,7 @@ static int sbp2_agent_reset(struct sbp2_lu *lu, int wait) return 0; } static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, static int sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, struct sbp2_fwhost_info *hi, struct sbp2_command_info *cmd, unsigned int scsi_use_sg, Loading @@ -1502,6 +1517,8 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, u32 orb_direction, enum dma_data_direction dma_dir) { struct device *dmadev = hi->host->device.parent; cmd->dma_dir = dma_dir; orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); orb->misc |= ORB_SET_DIRECTION(orb_direction); Loading @@ -1511,9 +1528,12 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, cmd->dma_size = sg->length; cmd->dma_type = CMD_DMA_PAGE; cmd->cmd_dma = dma_map_page(hi->host->device.parent, sg_page(sg), sg->offset, cmd->cmd_dma = dma_map_page(dmadev, sg_page(sg), sg->offset, cmd->dma_size, cmd->dma_dir); if (dma_mapping_error(dmadev, cmd->cmd_dma)) { cmd->cmd_dma = 0; return -ENOMEM; } orb->data_descriptor_lo = cmd->cmd_dma; orb->misc |= ORB_SET_DATA_SIZE(cmd->dma_size); Loading @@ -1523,8 +1543,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, &cmd->scatter_gather_element[0]; u32 sg_count, sg_len; dma_addr_t sg_addr; int i, count = dma_map_sg(hi->host->device.parent, sg, scsi_use_sg, dma_dir); int i, count = dma_map_sg(dmadev, sg, scsi_use_sg, dma_dir); cmd->dma_size = scsi_use_sg; cmd->sge_buffer = sg; Loading @@ -1533,7 +1552,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1); orb->data_descriptor_lo = cmd->sge_dma; dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma, dma_sync_single_for_cpu(dmadev, cmd->sge_dma, sizeof(cmd->scatter_gather_element), DMA_TO_DEVICE); Loading Loading @@ -1564,22 +1583,23 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, (sizeof(struct sbp2_unrestricted_page_table)) * sg_count); dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma, dma_sync_single_for_device(dmadev, cmd->sge_dma, sizeof(cmd->scatter_gather_element), DMA_TO_DEVICE); } return 0; } static void sbp2_create_command_orb(struct sbp2_lu *lu, static int sbp2_create_command_orb(struct sbp2_lu *lu, struct sbp2_command_info *cmd, struct scsi_cmnd *SCpnt) { struct device *dmadev = lu->hi->host->device.parent; struct sbp2_command_orb *orb = &cmd->command_orb; u32 orb_direction; unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt); enum dma_data_direction dma_dir = SCpnt->sc_data_direction; u32 orb_direction; int ret; dma_sync_single_for_cpu(dmadev, cmd->command_orb_dma, sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); Loading Loading @@ -1613,11 +1633,13 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu, orb->data_descriptor_hi = 0x0; orb->data_descriptor_lo = 0x0; orb->misc |= ORB_SET_DIRECTION(1); } else sbp2_prep_command_orb_sg(orb, lu->hi, cmd, scsi_sg_count(SCpnt), ret = 0; } else { ret = sbp2_prep_command_orb_sg(orb, lu->hi, cmd, scsi_sg_count(SCpnt), scsi_sglist(SCpnt), orb_direction, dma_dir); } sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); memset(orb->cdb, 0, sizeof(orb->cdb)); Loading @@ -1625,6 +1647,7 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu, dma_sync_single_for_device(dmadev, cmd->command_orb_dma, sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); return ret; } static void sbp2_link_orb_command(struct sbp2_lu *lu, Loading Loading @@ -1705,9 +1728,10 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt, if (!cmd) return -EIO; sbp2_create_command_orb(lu, cmd, SCpnt); sbp2_link_orb_command(lu, cmd); if (sbp2_create_command_orb(lu, cmd, SCpnt)) return -ENOMEM; sbp2_link_orb_command(lu, cmd); return 0; } Loading Loading
drivers/ieee1394/sbp2.c +59 −35 Original line number Diff line number Diff line Loading @@ -526,26 +526,41 @@ static void sbp2util_write_doorbell(struct work_struct *work) static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu) { struct sbp2_fwhost_info *hi = lu->hi; struct sbp2_command_info *cmd; struct device *dmadev = lu->hi->host->device.parent; int i, orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS; for (i = 0; i < orbs; i++) { cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; cmd->command_orb_dma = dma_map_single(hi->host->device.parent, &cmd->command_orb, goto failed_alloc; cmd->command_orb_dma = dma_map_single(dmadev, &cmd->command_orb, sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); cmd->sge_dma = dma_map_single(hi->host->device.parent, &cmd->scatter_gather_element, if (dma_mapping_error(dmadev, cmd->command_orb_dma)) goto failed_orb; cmd->sge_dma = dma_map_single(dmadev, &cmd->scatter_gather_element, sizeof(cmd->scatter_gather_element), DMA_TO_DEVICE); if (dma_mapping_error(dmadev, cmd->sge_dma)) goto failed_sge; INIT_LIST_HEAD(&cmd->list); list_add_tail(&cmd->list, &lu->cmd_orb_completed); } return 0; failed_sge: dma_unmap_single(dmadev, cmd->command_orb_dma, sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); failed_orb: kfree(cmd); failed_alloc: return -ENOMEM; } static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu, Loading Loading @@ -1494,7 +1509,7 @@ static int sbp2_agent_reset(struct sbp2_lu *lu, int wait) return 0; } static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, static int sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, struct sbp2_fwhost_info *hi, struct sbp2_command_info *cmd, unsigned int scsi_use_sg, Loading @@ -1502,6 +1517,8 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, u32 orb_direction, enum dma_data_direction dma_dir) { struct device *dmadev = hi->host->device.parent; cmd->dma_dir = dma_dir; orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); orb->misc |= ORB_SET_DIRECTION(orb_direction); Loading @@ -1511,9 +1528,12 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, cmd->dma_size = sg->length; cmd->dma_type = CMD_DMA_PAGE; cmd->cmd_dma = dma_map_page(hi->host->device.parent, sg_page(sg), sg->offset, cmd->cmd_dma = dma_map_page(dmadev, sg_page(sg), sg->offset, cmd->dma_size, cmd->dma_dir); if (dma_mapping_error(dmadev, cmd->cmd_dma)) { cmd->cmd_dma = 0; return -ENOMEM; } orb->data_descriptor_lo = cmd->cmd_dma; orb->misc |= ORB_SET_DATA_SIZE(cmd->dma_size); Loading @@ -1523,8 +1543,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, &cmd->scatter_gather_element[0]; u32 sg_count, sg_len; dma_addr_t sg_addr; int i, count = dma_map_sg(hi->host->device.parent, sg, scsi_use_sg, dma_dir); int i, count = dma_map_sg(dmadev, sg, scsi_use_sg, dma_dir); cmd->dma_size = scsi_use_sg; cmd->sge_buffer = sg; Loading @@ -1533,7 +1552,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1); orb->data_descriptor_lo = cmd->sge_dma; dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma, dma_sync_single_for_cpu(dmadev, cmd->sge_dma, sizeof(cmd->scatter_gather_element), DMA_TO_DEVICE); Loading Loading @@ -1564,22 +1583,23 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, (sizeof(struct sbp2_unrestricted_page_table)) * sg_count); dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma, dma_sync_single_for_device(dmadev, cmd->sge_dma, sizeof(cmd->scatter_gather_element), DMA_TO_DEVICE); } return 0; } static void sbp2_create_command_orb(struct sbp2_lu *lu, static int sbp2_create_command_orb(struct sbp2_lu *lu, struct sbp2_command_info *cmd, struct scsi_cmnd *SCpnt) { struct device *dmadev = lu->hi->host->device.parent; struct sbp2_command_orb *orb = &cmd->command_orb; u32 orb_direction; unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt); enum dma_data_direction dma_dir = SCpnt->sc_data_direction; u32 orb_direction; int ret; dma_sync_single_for_cpu(dmadev, cmd->command_orb_dma, sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); Loading Loading @@ -1613,11 +1633,13 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu, orb->data_descriptor_hi = 0x0; orb->data_descriptor_lo = 0x0; orb->misc |= ORB_SET_DIRECTION(1); } else sbp2_prep_command_orb_sg(orb, lu->hi, cmd, scsi_sg_count(SCpnt), ret = 0; } else { ret = sbp2_prep_command_orb_sg(orb, lu->hi, cmd, scsi_sg_count(SCpnt), scsi_sglist(SCpnt), orb_direction, dma_dir); } sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); memset(orb->cdb, 0, sizeof(orb->cdb)); Loading @@ -1625,6 +1647,7 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu, dma_sync_single_for_device(dmadev, cmd->command_orb_dma, sizeof(struct sbp2_command_orb), DMA_TO_DEVICE); return ret; } static void sbp2_link_orb_command(struct sbp2_lu *lu, Loading Loading @@ -1705,9 +1728,10 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt, if (!cmd) return -EIO; sbp2_create_command_orb(lu, cmd, SCpnt); sbp2_link_orb_command(lu, cmd); if (sbp2_create_command_orb(lu, cmd, SCpnt)) return -ENOMEM; sbp2_link_orb_command(lu, cmd); return 0; } Loading