aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath/ipath_file_ops.c
diff options
context:
space:
mode:
authorRobert Walsh <robert.walsh@qlogic.com>2007-06-18 17:24:49 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-09 23:12:26 -0400
commitf2d042313e420002b06715675963cfab48ed2597 (patch)
treeae149c8d21220aff9157952e39a7632be8c7ba61 /drivers/infiniband/hw/ipath/ipath_file_ops.c
parentb506e1dc59726a1c608f26e7294b9fe186255139 (diff)
IB/ipath: ipath_poll fixups and enhancements
Fix ipath_poll and enhance it so we can poll for urgent packets or regular packets and receive notifications of when a header queue overflows. Signed-off-by: Robert Walsh <robert.walsh@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_file_ops.c')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c125
1 files changed, 83 insertions, 42 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index a47479608f48..33ab0d6b80ff 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -1341,65 +1341,98 @@ bail:
1341 return ret; 1341 return ret;
1342} 1342}
1343 1343
1344static unsigned int ipath_poll(struct file *fp, 1344static unsigned int ipath_poll_urgent(struct ipath_portdata *pd,
1345 struct poll_table_struct *pt) 1345 struct file *fp,
1346 struct poll_table_struct *pt)
1346{ 1347{
1347 struct ipath_portdata *pd;
1348 u32 head, tail;
1349 int bit;
1350 unsigned pollflag = 0; 1348 unsigned pollflag = 0;
1351 struct ipath_devdata *dd; 1349 struct ipath_devdata *dd;
1352 1350
1353 pd = port_fp(fp);
1354 if (!pd)
1355 goto bail;
1356 dd = pd->port_dd; 1351 dd = pd->port_dd;
1357 1352
1358 bit = pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT; 1353 if (test_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag)) {
1359 set_bit(bit, &dd->ipath_rcvctrl); 1354 pollflag |= POLLERR;
1355 clear_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag);
1356 }
1360 1357
1361 /* 1358 if (test_bit(IPATH_PORT_WAITING_URG, &pd->int_flag)) {
1362 * Before blocking, make sure that head is still == tail, 1359 pollflag |= POLLIN | POLLRDNORM;
1363 * reading from the chip, so we can be sure the interrupt 1360 clear_bit(IPATH_PORT_WAITING_URG, &pd->int_flag);
1364 * enable has made it to the chip. If not equal, disable 1361 }
1365 * interrupt again and return immediately. This avoids races,
1366 * and the overhead of the chip read doesn't matter much at
1367 * this point, since we are waiting for something anyway.
1368 */
1369 1362
1370 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, 1363 if (!pollflag) {
1371 dd->ipath_rcvctrl); 1364 set_bit(IPATH_PORT_WAITING_URG, &pd->port_flag);
1365 if (pd->poll_type & IPATH_POLL_TYPE_OVERFLOW)
1366 set_bit(IPATH_PORT_WAITING_OVERFLOW,
1367 &pd->port_flag);
1368
1369 poll_wait(fp, &pd->port_wait, pt);
1370 }
1371
1372 return pollflag;
1373}
1374
1375static unsigned int ipath_poll_next(struct ipath_portdata *pd,
1376 struct file *fp,
1377 struct poll_table_struct *pt)
1378{
1379 u32 head, tail;
1380 unsigned pollflag = 0;
1381 struct ipath_devdata *dd;
1382
1383 dd = pd->port_dd;
1372 1384
1373 head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port); 1385 head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port);
1374 tail = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port); 1386 tail = *(volatile u64 *)pd->port_rcvhdrtail_kvaddr;
1387
1388 if (test_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag)) {
1389 pollflag |= POLLERR;
1390 clear_bit(IPATH_PORT_WAITING_OVERFLOW, &pd->int_flag);
1391 }
1375 1392
1376 if (tail == head) { 1393 if (tail != head ||
1394 test_bit(IPATH_PORT_WAITING_RCV, &pd->int_flag)) {
1395 pollflag |= POLLIN | POLLRDNORM;
1396 clear_bit(IPATH_PORT_WAITING_RCV, &pd->int_flag);
1397 }
1398
1399 if (!pollflag) {
1377 set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag); 1400 set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
1401 if (pd->poll_type & IPATH_POLL_TYPE_OVERFLOW)
1402 set_bit(IPATH_PORT_WAITING_OVERFLOW,
1403 &pd->port_flag);
1404
1405 set_bit(pd->port_port + INFINIPATH_R_INTRAVAIL_SHIFT,
1406 &dd->ipath_rcvctrl);
1407
1408 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
1409 dd->ipath_rcvctrl);
1410
1378 if (dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */ 1411 if (dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
1379 (void)ipath_write_ureg(dd, ur_rcvhdrhead, 1412 ipath_write_ureg(dd, ur_rcvhdrhead,
1380 dd->ipath_rhdrhead_intr_off 1413 dd->ipath_rhdrhead_intr_off | head,
1381 | head, pd->port_port); 1414 pd->port_port);
1382 poll_wait(fp, &pd->port_wait, pt);
1383 1415
1384 if (test_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag)) { 1416 poll_wait(fp, &pd->port_wait, pt);
1385 /* timed out, no packets received */
1386 clear_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
1387 pd->port_rcvwait_to++;
1388 }
1389 else
1390 pollflag = POLLIN | POLLRDNORM;
1391 }
1392 else {
1393 /* it's already happened; don't do wait_event overhead */
1394 pollflag = POLLIN | POLLRDNORM;
1395 pd->port_rcvnowait++;
1396 } 1417 }
1397 1418
1398 clear_bit(bit, &dd->ipath_rcvctrl); 1419 return pollflag;
1399 ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, 1420}
1400 dd->ipath_rcvctrl); 1421
1422static unsigned int ipath_poll(struct file *fp,
1423 struct poll_table_struct *pt)
1424{
1425 struct ipath_portdata *pd;
1426 unsigned pollflag;
1427
1428 pd = port_fp(fp);
1429 if (!pd)
1430 pollflag = 0;
1431 else if (pd->poll_type & IPATH_POLL_TYPE_URGENT)
1432 pollflag = ipath_poll_urgent(pd, fp, pt);
1433 else
1434 pollflag = ipath_poll_next(pd, fp, pt);
1401 1435
1402bail:
1403 return pollflag; 1436 return pollflag;
1404} 1437}
1405 1438
@@ -2173,6 +2206,11 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
2173 src = NULL; 2206 src = NULL;
2174 dest = NULL; 2207 dest = NULL;
2175 break; 2208 break;
2209 case IPATH_CMD_POLL_TYPE:
2210 copy = sizeof(cmd.cmd.poll_type);
2211 dest = &cmd.cmd.poll_type;
2212 src = &ucmd->cmd.poll_type;
2213 break;
2176 default: 2214 default:
2177 ret = -EINVAL; 2215 ret = -EINVAL;
2178 goto bail; 2216 goto bail;
@@ -2245,6 +2283,9 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
2245 case IPATH_CMD_PIOAVAILUPD: 2283 case IPATH_CMD_PIOAVAILUPD:
2246 ret = ipath_force_pio_avail_update(pd->port_dd); 2284 ret = ipath_force_pio_avail_update(pd->port_dd);
2247 break; 2285 break;
2286 case IPATH_CMD_POLL_TYPE:
2287 pd->poll_type = cmd.cmd.poll_type;
2288 break;
2248 } 2289 }
2249 2290
2250 if (ret >= 0) 2291 if (ret >= 0)