Commit 2db01da8 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by Vasily Gorbik

s390/qdio: fill SBALEs with absolute addresses

sbale->addr holds an absolute address (or for some FCP usage, an opaque
request ID), and should only be used with proper virt/phys translation.
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: default avatarBenjamin Block <bblock@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent e9091ffd
...@@ -201,7 +201,7 @@ struct slib { ...@@ -201,7 +201,7 @@ struct slib {
* @scount: SBAL count * @scount: SBAL count
* @sflags: whole SBAL flags * @sflags: whole SBAL flags
* @length: length * @length: length
* @addr: address * @addr: absolute data address
*/ */
struct qdio_buffer_element { struct qdio_buffer_element {
u8 eflags; u8 eflags;
...@@ -211,7 +211,7 @@ struct qdio_buffer_element { ...@@ -211,7 +211,7 @@ struct qdio_buffer_element {
u8 scount; u8 scount;
u8 sflags; u8 sflags;
u32 length; u32 length;
void *addr; u64 addr;
} __attribute__ ((packed, aligned(16))); } __attribute__ ((packed, aligned(16)));
/** /**
......
...@@ -1128,9 +1128,10 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, ...@@ -1128,9 +1128,10 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
qeth_tx_complete_buf(buf, error, budget); qeth_tx_complete_buf(buf, error, budget);
for (i = 0; i < queue->max_elements; ++i) { for (i = 0; i < queue->max_elements; ++i) {
if (buf->buffer->element[i].addr && buf->is_header[i]) void *data = phys_to_virt(buf->buffer->element[i].addr);
kmem_cache_free(qeth_core_header_cache,
buf->buffer->element[i].addr); if (data && buf->is_header[i])
kmem_cache_free(qeth_core_header_cache, data);
buf->is_header[i] = 0; buf->is_header[i] = 0;
} }
...@@ -2641,7 +2642,8 @@ static int qeth_init_input_buffer(struct qeth_card *card, ...@@ -2641,7 +2642,8 @@ static int qeth_init_input_buffer(struct qeth_card *card,
buf->pool_entry = pool_entry; buf->pool_entry = pool_entry;
for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) { for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
buf->buffer->element[i].length = PAGE_SIZE; buf->buffer->element[i].length = PAGE_SIZE;
buf->buffer->element[i].addr = pool_entry->elements[i]; buf->buffer->element[i].addr =
virt_to_phys(pool_entry->elements[i]);
if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1) if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1)
buf->buffer->element[i].eflags = SBAL_EFLAGS_LAST_ENTRY; buf->buffer->element[i].eflags = SBAL_EFLAGS_LAST_ENTRY;
else else
...@@ -3459,9 +3461,8 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err, ...@@ -3459,9 +3461,8 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err,
while ((e < QDIO_MAX_ELEMENTS_PER_BUFFER) && while ((e < QDIO_MAX_ELEMENTS_PER_BUFFER) &&
buffer->element[e].addr) { buffer->element[e].addr) {
unsigned long phys_aob_addr; unsigned long phys_aob_addr = buffer->element[e].addr;
phys_aob_addr = (unsigned long) buffer->element[e].addr;
qeth_qdio_handle_aob(card, phys_aob_addr); qeth_qdio_handle_aob(card, phys_aob_addr);
++e; ++e;
} }
...@@ -3750,7 +3751,7 @@ static unsigned int __qeth_fill_buffer(struct sk_buff *skb, ...@@ -3750,7 +3751,7 @@ static unsigned int __qeth_fill_buffer(struct sk_buff *skb,
elem_length = min_t(unsigned int, length, elem_length = min_t(unsigned int, length,
PAGE_SIZE - offset_in_page(data)); PAGE_SIZE - offset_in_page(data));
buffer->element[element].addr = data; buffer->element[element].addr = virt_to_phys(data);
buffer->element[element].length = elem_length; buffer->element[element].length = elem_length;
length -= elem_length; length -= elem_length;
if (is_first_elem) { if (is_first_elem) {
...@@ -3780,7 +3781,7 @@ static unsigned int __qeth_fill_buffer(struct sk_buff *skb, ...@@ -3780,7 +3781,7 @@ static unsigned int __qeth_fill_buffer(struct sk_buff *skb,
elem_length = min_t(unsigned int, length, elem_length = min_t(unsigned int, length,
PAGE_SIZE - offset_in_page(data)); PAGE_SIZE - offset_in_page(data));
buffer->element[element].addr = data; buffer->element[element].addr = virt_to_phys(data);
buffer->element[element].length = elem_length; buffer->element[element].length = elem_length;
buffer->element[element].eflags = buffer->element[element].eflags =
SBAL_EFLAGS_MIDDLE_FRAG; SBAL_EFLAGS_MIDDLE_FRAG;
...@@ -3820,7 +3821,7 @@ static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf, ...@@ -3820,7 +3821,7 @@ static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf,
int element = buf->next_element_to_fill; int element = buf->next_element_to_fill;
is_first_elem = false; is_first_elem = false;
buffer->element[element].addr = hdr; buffer->element[element].addr = virt_to_phys(hdr);
buffer->element[element].length = hd_len; buffer->element[element].length = hd_len;
buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG; buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG;
/* remember to free cache-allocated qeth_hdr: */ /* remember to free cache-allocated qeth_hdr: */
...@@ -5288,7 +5289,7 @@ static int qeth_extract_skb(struct qeth_card *card, ...@@ -5288,7 +5289,7 @@ static int qeth_extract_skb(struct qeth_card *card,
offset = 0; offset = 0;
} }
hdr = element->addr + offset; hdr = phys_to_virt(element->addr) + offset;
offset += sizeof(*hdr); offset += sizeof(*hdr);
skb = NULL; skb = NULL;
...@@ -5387,7 +5388,7 @@ static int qeth_extract_skb(struct qeth_card *card, ...@@ -5387,7 +5388,7 @@ static int qeth_extract_skb(struct qeth_card *card,
walk_packet: walk_packet:
while (skb_len) { while (skb_len) {
int data_len = min(skb_len, (int)(element->length - offset)); int data_len = min(skb_len, (int)(element->length - offset));
char *data = element->addr + offset; char *data = phys_to_virt(element->addr) + offset;
skb_len -= data_len; skb_len -= data_len;
offset += data_len; offset += data_len;
......
...@@ -2510,7 +2510,7 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) ...@@ -2510,7 +2510,7 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) { for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {
sbale = &sbal->element[idx]; sbale = &sbal->element[idx];
req_id = (unsigned long) sbale->addr; req_id = sbale->addr;
fsf_req = zfcp_reqlist_find_rm(adapter->req_list, req_id); fsf_req = zfcp_reqlist_find_rm(adapter->req_list, req_id);
if (!fsf_req) { if (!fsf_req) {
......
...@@ -98,7 +98,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, ...@@ -98,7 +98,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
memset(pl, 0, memset(pl, 0,
ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *)); ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
sbale = qdio->res_q[idx]->element; sbale = qdio->res_q[idx]->element;
req_id = (u64) sbale->addr; req_id = sbale->addr;
scount = min(sbale->scount + 1, scount = min(sbale->scount + 1,
ZFCP_QDIO_MAX_SBALS_PER_REQ + 1); ZFCP_QDIO_MAX_SBALS_PER_REQ + 1);
/* incl. signaling SBAL */ /* incl. signaling SBAL */
...@@ -199,7 +199,7 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, ...@@ -199,7 +199,7 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
q_req->sbal_number); q_req->sbal_number);
return -EINVAL; return -EINVAL;
} }
sbale->addr = sg_virt(sg); sbale->addr = sg_phys(sg);
sbale->length = sg->length; sbale->length = sg->length;
} }
return 0; return 0;
...@@ -418,7 +418,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio) ...@@ -418,7 +418,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
sbale->length = 0; sbale->length = 0;
sbale->eflags = SBAL_EFLAGS_LAST_ENTRY; sbale->eflags = SBAL_EFLAGS_LAST_ENTRY;
sbale->sflags = 0; sbale->sflags = 0;
sbale->addr = NULL; sbale->addr = 0;
} }
if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q)) if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q))
......
...@@ -122,14 +122,14 @@ void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, ...@@ -122,14 +122,14 @@ void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
% QDIO_MAX_BUFFERS_PER_Q; % QDIO_MAX_BUFFERS_PER_Q;
sbale = zfcp_qdio_sbale_req(qdio, q_req); sbale = zfcp_qdio_sbale_req(qdio, q_req);
sbale->addr = (void *) req_id; sbale->addr = req_id;
sbale->eflags = 0; sbale->eflags = 0;
sbale->sflags = SBAL_SFLAGS0_COMMAND | sbtype; sbale->sflags = SBAL_SFLAGS0_COMMAND | sbtype;
if (unlikely(!data)) if (unlikely(!data))
return; return;
sbale++; sbale++;
sbale->addr = data; sbale->addr = virt_to_phys(data);
sbale->length = len; sbale->length = len;
} }
...@@ -152,7 +152,7 @@ void zfcp_qdio_fill_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, ...@@ -152,7 +152,7 @@ void zfcp_qdio_fill_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
BUG_ON(q_req->sbale_curr == qdio->max_sbale_per_sbal - 1); BUG_ON(q_req->sbale_curr == qdio->max_sbale_per_sbal - 1);
q_req->sbale_curr++; q_req->sbale_curr++;
sbale = zfcp_qdio_sbale_curr(qdio, q_req); sbale = zfcp_qdio_sbale_curr(qdio, q_req);
sbale->addr = data; sbale->addr = virt_to_phys(data);
sbale->length = len; sbale->length = len;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment