Browse Source

isci: have the driver use native SG calls and DMA-API

Remove abstraction for SG building and get rid of callbacks for getting
DMA memory mapping.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Dave Jiang 14 years ago
parent
commit
6389a77596

+ 15 - 0
drivers/scsi/isci/core/sci_util.c

@@ -84,3 +84,18 @@ void *scic_request_get_virt_addr(struct scic_sds_request *sci_req, dma_addr_t ph
 	return (char *)ireq + offset;
 }
 
+dma_addr_t scic_io_request_get_dma_addr(struct scic_sds_request *sds_request,
+					void *virt_addr)
+{
+	struct isci_request *isci_request =
+		(struct isci_request *)sci_object_get_association(sds_request);
+
+	char *requested_addr = (char *)virt_addr;
+	char *base_addr = (char *)isci_request;
+
+	BUG_ON(requested_addr < base_addr);
+	BUG_ON((requested_addr - base_addr) >=
+			isci_request->request_alloc_size);
+
+	return isci_request->request_daddr + (requested_addr - base_addr);
+}

+ 3 - 0
drivers/scsi/isci/core/sci_util.h

@@ -102,4 +102,7 @@ void scic_word_copy_with_swap(u32 *destination, u32 *source, u32 word_count);
 void *scic_request_get_virt_addr(struct scic_sds_request *sds_request,
 				 dma_addr_t phys_addr);
 
+dma_addr_t scic_io_request_get_dma_addr(struct scic_sds_request *sds_request,
+					void *virt_addr);
+
 #endif /* _SCI_UTIL_H_ */

+ 108 - 100
drivers/scsi/isci/core/scic_sds_request.c

@@ -259,56 +259,70 @@ static struct scu_sgl_element_pair *scic_sds_request_get_sgl_element_pair(
  *    the Scatter-Gather List.
  *
  */
-void scic_sds_request_build_sgl(
-	struct scic_sds_request *this_request)
+void scic_sds_request_build_sgl(struct scic_sds_request *sds_request)
 {
-	void *os_sge;
-	void *os_handle;
-	dma_addr_t physical_address;
-	u32 sgl_pair_index = 0;
-	struct scu_sgl_element_pair *scu_sgl_list   = NULL;
-	struct scu_sgl_element_pair *previous_pair  = NULL;
-
-	os_handle = scic_sds_request_get_user_request(this_request);
-	scic_cb_io_request_get_next_sge(os_handle, NULL, &os_sge);
-
-	while (os_sge != NULL) {
-		scu_sgl_list =
-			scic_sds_request_get_sgl_element_pair(this_request, sgl_pair_index);
-
-		SCU_SGL_COPY(os_handle, scu_sgl_list->A, os_sge);
-
-		scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge);
-
-		if (os_sge != NULL) {
-			SCU_SGL_COPY(os_handle, scu_sgl_list->B, os_sge);
-
-			scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge);
-		} else {
-			SCU_SGL_ZERO(scu_sgl_list->B);
+	struct isci_request *isci_request =
+		(struct isci_request *)sci_object_get_association(sds_request);
+	struct isci_host *isci_host = isci_request->isci_host;
+	struct sas_task *task = isci_request_access_task(isci_request);
+	struct scatterlist *sg = NULL;
+	dma_addr_t dma_addr;
+	u32 sg_idx = 0;
+	struct scu_sgl_element_pair *scu_sg   = NULL;
+	struct scu_sgl_element_pair *prev_sg  = NULL;
+
+	if (task->num_scatter > 0) {
+		sg = task->scatter;
+
+		while (sg) {
+			scu_sg = scic_sds_request_get_sgl_element_pair(
+					sds_request,
+					sg_idx);
+
+			SCU_SGL_COPY(scu_sg->A, sg);
+
+			sg = sg_next(sg);
+
+			if (sg) {
+				SCU_SGL_COPY(scu_sg->B, sg);
+				sg = sg_next(sg);
+			} else
+				SCU_SGL_ZERO(scu_sg->B);
+
+			if (prev_sg) {
+				dma_addr =
+					scic_io_request_get_dma_addr(
+							sds_request,
+							scu_sg);
+
+				prev_sg->next_pair_upper =
+					upper_32_bits(dma_addr);
+				prev_sg->next_pair_lower =
+					lower_32_bits(dma_addr);
+			}
+
+			prev_sg = scu_sg;
+			sg_idx++;
 		}
+	} else {	/* handle when no sg */
+		scu_sg = scic_sds_request_get_sgl_element_pair(sds_request,
+							       sg_idx);
 
-		if (previous_pair != NULL) {
-			scic_cb_io_request_get_physical_address(
-				scic_sds_request_get_controller(this_request),
-				this_request,
-				scu_sgl_list,
-				&physical_address
-				);
+		dma_addr = dma_map_single(&isci_host->pdev->dev,
+					  task->scatter,
+					  task->total_xfer_len,
+					  task->data_dir);
 
-			previous_pair->next_pair_upper =
-				upper_32_bits(physical_address);
-			previous_pair->next_pair_lower =
-				lower_32_bits(physical_address);
-		}
+		isci_request->zero_scatter_daddr = dma_addr;
 
-		previous_pair = scu_sgl_list;
-		sgl_pair_index++;
+		scu_sg->A.length = task->total_xfer_len;
+		scu_sg->A.address_upper = upper_32_bits(dma_addr);
+		scu_sg->A.address_lower = lower_32_bits(dma_addr);
 	}
 
-	if (scu_sgl_list != NULL) {
-		scu_sgl_list->next_pair_upper = 0;
-		scu_sgl_list->next_pair_lower = 0;
+	if (scu_sg) {
+		scu_sg->next_pair_upper = 0;
+		scu_sg->next_pair_lower = 0;
 	}
 }
 
@@ -473,17 +487,17 @@ static void scic_sds_task_request_build_ssp_task_iu(
  *
  */
 static void scu_ssp_reqeust_construct_task_context(
-	struct scic_sds_request *this_request,
+	struct scic_sds_request *sds_request,
 	struct scu_task_context *task_context)
 {
-	dma_addr_t physical_address;
-	struct scic_sds_controller *owning_controller;
+	dma_addr_t dma_addr;
+	struct scic_sds_controller *controller;
 	struct scic_sds_remote_device *target_device;
 	struct scic_sds_port *target_port;
 
-	owning_controller = scic_sds_request_get_controller(this_request);
-	target_device = scic_sds_request_get_device(this_request);
-	target_port = scic_sds_request_get_port(this_request);
+	controller = scic_sds_request_get_controller(sds_request);
+	target_device = scic_sds_request_get_device(sds_request);
+	target_port = scic_sds_request_get_port(sds_request);
 
 	/* Fill in the TC with the its required data */
 	task_context->abort = 0;
@@ -492,7 +506,7 @@ static void scu_ssp_reqeust_construct_task_context(
 	task_context->connection_rate =
 		scic_remote_device_get_connection_rate(target_device);
 	task_context->protocol_engine_index =
-		scic_sds_controller_get_protocol_engine_group(owning_controller);
+		scic_sds_controller_get_protocol_engine_group(controller);
 	task_context->logical_port_index =
 		scic_sds_port_get_index(target_port);
 	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
@@ -500,7 +514,7 @@ static void scu_ssp_reqeust_construct_task_context(
 	task_context->context_type = SCU_TASK_CONTEXT_TYPE;
 
 	task_context->remote_node_index =
-		scic_sds_remote_device_get_index(this_request->target_device);
+		scic_sds_remote_device_get_index(sds_request->target_device);
 	task_context->command_code = 0;
 
 	task_context->link_layer_control = 0;
@@ -515,61 +529,55 @@ static void scu_ssp_reqeust_construct_task_context(
 	/* task_context->type.ssp.tag = this_request->io_tag; */
 	task_context->task_phase = 0x01;
 
-	if (this_request->was_tag_assigned_by_user) {
-		/* Build the task context now since we have already read the data */
-		this_request->post_context = (
-			SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
-			| (
-				scic_sds_controller_get_protocol_engine_group(owning_controller)
-				<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
-				)
-			| (
-				scic_sds_port_get_index(target_port)
-				<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
-				)
-			| scic_sds_io_tag_get_index(this_request->io_tag)
-			);
+	if (sds_request->was_tag_assigned_by_user) {
+		/*
+		 * Build the task context now since we have already read
+		 * the data
+		 */
+		sds_request->post_context =
+			(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			 (scic_sds_controller_get_protocol_engine_group(
+							controller) <<
+			  SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			 (scic_sds_port_get_index(target_port) <<
+			  SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
+			 scic_sds_io_tag_get_index(sds_request->io_tag));
 	} else {
-		/* Build the task context now since we have already read the data */
-		this_request->post_context = (
-			SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
-			| (
-				scic_sds_controller_get_protocol_engine_group(owning_controller)
-				<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
-				)
-			| (
-				scic_sds_port_get_index(target_port)
-				<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
-				)
-			/* This is not assigned because we have to wait until we get a TCi */
-			);
+		/*
+		 * Build the task context now since we have already read
+		 * the data
+		 *
+		 * I/O tag index is not assigned because we have to wait
+		 * until we get a TCi
+		 */
+		sds_request->post_context =
+			(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			 (scic_sds_controller_get_protocol_engine_group(
+							owning_controller) <<
+			  SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			 (scic_sds_port_get_index(target_port) <<
+			  SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
 	}
 
-	/* Copy the physical address for the command buffer to the SCU Task Context */
-	scic_cb_io_request_get_physical_address(
-		scic_sds_request_get_controller(this_request),
-		this_request,
-		this_request->command_buffer,
-		&physical_address
-		);
+	/*
+	 * Copy the physical address for the command buffer to the
+	 * SCU Task Context
+	 */
+	dma_addr = scic_io_request_get_dma_addr(sds_request,
+						sds_request->command_buffer);
 
-	task_context->command_iu_upper =
-		upper_32_bits(physical_address);
-	task_context->command_iu_lower =
-		lower_32_bits(physical_address);
+	task_context->command_iu_upper = upper_32_bits(dma_addr);
+	task_context->command_iu_lower = lower_32_bits(dma_addr);
 
-	/* Copy the physical address for the response buffer to the SCU Task Context */
-	scic_cb_io_request_get_physical_address(
-		scic_sds_request_get_controller(this_request),
-		this_request,
-		this_request->response_buffer,
-		&physical_address
-		);
+	/*
+	 * Copy the physical address for the response buffer to the
+	 * SCU Task Context
+	 */
+	dma_addr = scic_io_request_get_dma_addr(sds_request,
+						sds_request->response_buffer);
 
-	task_context->response_iu_upper =
-		upper_32_bits(physical_address);
-	task_context->response_iu_lower =
-		lower_32_bits(physical_address);
+	task_context->response_iu_upper = upper_32_bits(dma_addr);
+	task_context->response_iu_lower = lower_32_bits(dma_addr);
 }
 
 /**

+ 4 - 5
drivers/scsi/isci/core/scic_sds_request.h

@@ -389,14 +389,13 @@ extern const struct scic_sds_io_request_state_handler scic_sds_smp_request_start
  * This macro copys the SGL Element data from the host os to the hardware SGL
  * elment data
  */
-#define SCU_SGL_COPY(os_handle, scu_sge, os_sge) \
+#define SCU_SGL_COPY(scu_sge, os_sge) \
 	{ \
-		(scu_sge).length = \
-			scic_cb_sge_get_length_field(os_handle, os_sge); \
+		(scu_sge).length = sg_dma_len(sg); \
 		(scu_sge).address_upper = \
-			upper_32_bits(scic_cb_sge_get_address_field(os_handle, os_sge)); \
+			upper_32_bits(sg_dma_address(sg)); \
 		(scu_sge).address_lower = \
-			lower_32_bits(scic_cb_sge_get_address_field(os_handle, os_sge)); \
+			lower_32_bits(sg_dma_address(sg)); \
 		(scu_sge).address_modifier = 0;	\
 	}
 

+ 59 - 60
drivers/scsi/isci/core/scic_sds_smp_request.c

@@ -234,37 +234,36 @@ enum sci_status scic_io_request_construct_smp(
  *
  */
 static void scu_smp_request_construct_task_context(
-	struct scic_sds_request *this_request,
+	struct scic_sds_request *sds_request,
 	struct smp_request *smp_request)
 {
-	dma_addr_t physical_address;
-	struct scic_sds_controller *owning_controller;
+	dma_addr_t dma_addr;
+	struct scic_sds_controller *controller;
 	struct scic_sds_remote_device *target_device;
 	struct scic_sds_port *target_port;
 	struct scu_task_context *task_context;
 
 	/* byte swap the smp request. */
-	scic_word_copy_with_swap(
-		this_request->command_buffer,
-		(u32 *)smp_request,
-		sizeof(struct smp_request) / sizeof(u32)
-		);
+	scic_word_copy_with_swap(sds_request->command_buffer,
+				 (u32 *)smp_request,
+				 sizeof(struct smp_request) / sizeof(u32));
 
-	task_context = scic_sds_request_get_task_context(this_request);
+	task_context = scic_sds_request_get_task_context(sds_request);
 
-	owning_controller = scic_sds_request_get_controller(this_request);
-	target_device = scic_sds_request_get_device(this_request);
-	target_port = scic_sds_request_get_port(this_request);
+	controller = scic_sds_request_get_controller(sds_request);
+	target_device = scic_sds_request_get_device(sds_request);
+	target_port = scic_sds_request_get_port(sds_request);
 
 	/*
 	 * Fill in the TC with the its required data
-	 * 00h */
+	 * 00h
+	 */
 	task_context->priority = 0;
 	task_context->initiator_request = 1;
 	task_context->connection_rate =
 		scic_remote_device_get_connection_rate(target_device);
 	task_context->protocol_engine_index =
-		scic_sds_controller_get_protocol_engine_group(owning_controller);
+		scic_sds_controller_get_protocol_engine_group(controller);
 	task_context->logical_port_index =
 		scic_sds_port_get_index(target_port);
 	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
@@ -273,7 +272,8 @@ static void scu_smp_request_construct_task_context(
 	task_context->context_type = SCU_TASK_CONTEXT_TYPE;
 
 	/* 04h */
-	task_context->remote_node_index = this_request->target_device->rnc->remote_node_index;
+	task_context->remote_node_index =
+		sds_request->target_device->rnc->remote_node_index;
 	task_context->command_code = 0;
 	task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST;
 
@@ -289,7 +289,8 @@ static void scu_smp_request_construct_task_context(
 	task_context->address_modifier = 0;
 
 	/* 10h */
-	task_context->ssp_command_iu_length = smp_request->header.request_length;
+	task_context->ssp_command_iu_length =
+		smp_request->header.request_length;
 
 	/* 14h */
 	task_context->transfer_length_bytes = 0;
@@ -298,59 +299,57 @@ static void scu_smp_request_construct_task_context(
 	 * 18h ~ 30h, protocol specific
 	 * since commandIU has been build by framework at this point, we just
 	 * copy the frist DWord from command IU to this location. */
-	memcpy((void *)(&task_context->type.smp), this_request->command_buffer, sizeof(u32));
+	memcpy((void *)(&task_context->type.smp),
+	       sds_request->command_buffer,
+	       sizeof(u32));
 
 	/*
 	 * 40h
-	 * "For SMP you could program it to zero. We would prefer that way so that
-	 * done code will be consistent." - Venki */
+	 * "For SMP you could program it to zero. We would prefer that way
+	 * so that done code will be consistent." - Venki
+	 */
 	task_context->task_phase = 0;
 
-	if (this_request->was_tag_assigned_by_user) {
-		/* Build the task context now since we have already read the data */
-		this_request->post_context = (
-			SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
-			| (
-				scic_sds_controller_get_protocol_engine_group(owning_controller)
-				<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
-				)
-			| (
-				scic_sds_port_get_index(target_port)
-				<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
-				)
-			| scic_sds_io_tag_get_index(this_request->io_tag)
-			);
+	if (sds_request->was_tag_assigned_by_user) {
+		/*
+		 * Build the task context now since we have already read
+		 * the data
+		 */
+		sds_request->post_context =
+			(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			 (scic_sds_controller_get_protocol_engine_group(
+							controller) <<
+			  SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			 (scic_sds_port_get_index(target_port) <<
+			  SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
+			 scic_sds_io_tag_get_index(sds_request->io_tag));
 	} else {
-		/* Build the task context now since we have already read the data */
-		this_request->post_context = (
-			SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
-			| (
-				scic_sds_controller_get_protocol_engine_group(owning_controller)
-				<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
-				)
-			| (
-				scic_sds_port_get_index(target_port)
-				<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
-				)
-			/* This is not assigned because we have to wait until we get a TCi */
-			);
+		/*
+		 * Build the task context now since we have already read
+		 * the data.
+		 * I/O tag index is not assigned because we have to wait
+		 * until we get a TCi.
+		 */
+		sds_request->post_context =
+			(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			 (scic_sds_controller_get_protocol_engine_group(
+							controller) <<
+			  SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			 (scic_sds_port_get_index(target_port) <<
+			  SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
 	}
 
 	/*
-	 * Copy the physical address for the command buffer to the SCU Task Context
-	 * command buffer should not contain command header. */
-	scic_cb_io_request_get_physical_address(
-		scic_sds_request_get_controller(this_request),
-		this_request,
-		((char *)(this_request->command_buffer) + sizeof(u32)),
-		&physical_address
-		);
-
-	task_context->command_iu_upper =
-		upper_32_bits(physical_address);
-	task_context->command_iu_lower =
-		lower_32_bits(physical_address);
-
+	 * Copy the physical address for the command buffer to the SCU Task
+	 * Context command buffer should not contain command header.
+	 */
+	dma_addr = scic_io_request_get_dma_addr(sds_request,
+						(char *)
+						(sds_request->command_buffer) +
+						sizeof(u32));
+
+	task_context->command_iu_upper = upper_32_bits(dma_addr);
+	task_context->command_iu_lower = lower_32_bits(dma_addr);
 
 	/* SMP response comes as UF, so no need to set response IU address. */
 	task_context->response_iu_upper = 0;

+ 8 - 12
drivers/scsi/isci/core/scic_sds_stp_packet_request.c

@@ -253,30 +253,26 @@ enum sci_status scic_sds_stp_packet_request_process_status_fis(
  *
  */
 void scic_sds_stp_packet_internal_request_sense_build_sgl(
-	struct scic_sds_request *this_request)
+	struct scic_sds_request *sds_request)
 {
 	void *sge;
 	struct scu_sgl_element_pair *scu_sgl_list   = NULL;
 	struct scu_task_context *task_context;
-	dma_addr_t physical_address;
+	dma_addr_t dma_addr;
 
 	struct sci_ssp_response_iu *rsp_iu =
-		(struct sci_ssp_response_iu *)this_request->response_buffer;
+		(struct sci_ssp_response_iu *)sds_request->response_buffer;
 
 	sge =  (void *)&rsp_iu->data[0];
 
-	task_context = (struct scu_task_context *)this_request->task_context_buffer;
+	task_context =
+		(struct scu_task_context *)sds_request->task_context_buffer;
 	scu_sgl_list = &task_context->sgl_pair_ab;
 
-	scic_cb_io_request_get_physical_address(
-		scic_sds_request_get_controller(this_request),
-		this_request,
-		((char *)sge),
-		&physical_address
-		);
+	dma_addr = scic_io_request_get_dma_addr(sds_request, sge);
 
-	scu_sgl_list->A.address_upper = sci_cb_physical_address_upper(physical_address);
-	scu_sgl_list->A.address_lower = sci_cb_physical_address_lower(physical_address);
+	scu_sgl_list->A.address_upper = upper_32_bits(dma_addr);
+	scu_sgl_list->A.address_lower = lower_32_bits(dma_addr);
 	scu_sgl_list->A.length = task_context->transfer_length_bytes;
 	scu_sgl_list->A.address_modifier = 0;
 

+ 48 - 51
drivers/scsi/isci/core/scic_sds_stp_request.c

@@ -175,17 +175,17 @@ void scic_sds_stp_request_assign_buffers(
  * determine what is common for SSP/SMP/STP task context structures.
  */
 static void scu_sata_reqeust_construct_task_context(
-	struct scic_sds_request *this_request,
+	struct scic_sds_request *sds_request,
 	struct scu_task_context *task_context)
 {
-	dma_addr_t physical_address;
-	struct scic_sds_controller *owning_controller;
+	dma_addr_t dma_addr;
+	struct scic_sds_controller *controller;
 	struct scic_sds_remote_device *target_device;
 	struct scic_sds_port *target_port;
 
-	owning_controller = scic_sds_request_get_controller(this_request);
-	target_device = scic_sds_request_get_device(this_request);
-	target_port = scic_sds_request_get_port(this_request);
+	controller = scic_sds_request_get_controller(sds_request);
+	target_device = scic_sds_request_get_device(sds_request);
+	target_port = scic_sds_request_get_port(sds_request);
 
 	/* Fill in the TC with the its required data */
 	task_context->abort = 0;
@@ -194,7 +194,7 @@ static void scu_sata_reqeust_construct_task_context(
 	task_context->connection_rate =
 		scic_remote_device_get_connection_rate(target_device);
 	task_context->protocol_engine_index =
-		scic_sds_controller_get_protocol_engine_group(owning_controller);
+		scic_sds_controller_get_protocol_engine_group(controller);
 	task_context->logical_port_index =
 		scic_sds_port_get_index(target_port);
 	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
@@ -202,7 +202,7 @@ static void scu_sata_reqeust_construct_task_context(
 	task_context->context_type = SCU_TASK_CONTEXT_TYPE;
 
 	task_context->remote_node_index =
-		scic_sds_remote_device_get_index(this_request->target_device);
+		scic_sds_remote_device_get_index(sds_request->target_device);
 	task_context->command_code = 0;
 
 	task_context->link_layer_control = 0;
@@ -219,53 +219,50 @@ static void scu_sata_reqeust_construct_task_context(
 		(sizeof(struct sata_fis_reg_h2d) - sizeof(u32)) / sizeof(u32);
 
 	/* Set the first word of the H2D REG FIS */
-	task_context->type.words[0] = *(u32 *)this_request->command_buffer;
-
-	if (this_request->was_tag_assigned_by_user) {
-		/* Build the task context now since we have already read the data */
-		this_request->post_context = (
-			SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
-			| (
-				scic_sds_controller_get_protocol_engine_group(owning_controller)
-				<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
-				)
-			| (
-				scic_sds_port_get_index(target_port)
-				<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
-				)
-			| scic_sds_io_tag_get_index(this_request->io_tag)
-			);
+	task_context->type.words[0] = *(u32 *)sds_request->command_buffer;
+
+	if (sds_request->was_tag_assigned_by_user) {
+		/*
+		 * Build the task context now since we have already read
+		 * the data
+		 */
+		sds_request->post_context =
+			(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			 (scic_sds_controller_get_protocol_engine_group(
+							controller) <<
+			  SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			 (scic_sds_port_get_index(target_port) <<
+			  SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
+			 scic_sds_io_tag_get_index(sds_request->io_tag));
 	} else {
-		/* Build the task context now since we have already read the data */
-		this_request->post_context = (
-			SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
-			| (
-				scic_sds_controller_get_protocol_engine_group(owning_controller)
-				<< SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
-				)
-			| (
-				scic_sds_port_get_index(target_port)
-				<< SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
-				)
-			/* This is not assigned because we have to wait until we get a TCi */
-			);
+		/*
+		 * Build the task context now since we have already read
+		 * the data.
+		 * I/O tag index is not assigned because we have to wait
+		 * until we get a TCi.
+		 */
+		sds_request->post_context =
+			(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			 (scic_sds_controller_get_protocol_engine_group(
+							controller) <<
+			  SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			 (scic_sds_port_get_index(target_port) <<
+			  SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT));
 	}
 
 	/*
-	 * Copy the physical address for the command buffer to the SCU Task Context
-	 * We must offset the command buffer by 4 bytes because the first 4 bytes are
-	 * transfered in the body of the TC */
-	scic_cb_io_request_get_physical_address(
-		scic_sds_request_get_controller(this_request),
-		this_request,
-		((char *)this_request->command_buffer) + sizeof(u32),
-		&physical_address
-		);
-
-	task_context->command_iu_upper =
-		upper_32_bits(physical_address);
-	task_context->command_iu_lower =
-		lower_32_bits(physical_address);
+	 * Copy the physical address for the command buffer to the SCU Task
+	 * Context. We must offset the command buffer by 4 bytes because the
+	 * first 4 bytes are transfered in the body of the TC.
+	 */
+	dma_addr =
+		scic_io_request_get_dma_addr(sds_request,
+						(char *)sds_request->
+							command_buffer +
+							sizeof(u32));
+
+	task_context->command_iu_upper = upper_32_bits(dma_addr);
+	task_context->command_iu_lower = lower_32_bits(dma_addr);
 
 	/* SATA Requests do not have a response buffer */
 	task_context->response_iu_upper = 0;