aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/megaraid.c')
-rw-r--r--drivers/scsi/megaraid.c141
1 files changed, 30 insertions, 111 deletions
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 3cce75d70263..3907f6718ede 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -523,10 +523,8 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
523 /* 523 /*
524 * filter the internal and ioctl commands 524 * filter the internal and ioctl commands
525 */ 525 */
526 if((cmd->cmnd[0] == MEGA_INTERNAL_CMD)) { 526 if((cmd->cmnd[0] == MEGA_INTERNAL_CMD))
527 return cmd->request_buffer; 527 return (scb_t *)cmd->host_scribble;
528 }
529
530 528
531 /* 529 /*
532 * We know what channels our logical drives are on - mega_find_card() 530 * We know what channels our logical drives are on - mega_find_card()
@@ -657,22 +655,14 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
657 655
658 case MODE_SENSE: { 656 case MODE_SENSE: {
659 char *buf; 657 char *buf;
658 struct scatterlist *sg;
660 659
661 if (cmd->use_sg) { 660 sg = scsi_sglist(cmd);
662 struct scatterlist *sg; 661 buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
663 662
664 sg = (struct scatterlist *)cmd->request_buffer;
665 buf = kmap_atomic(sg->page, KM_IRQ0) +
666 sg->offset;
667 } else
668 buf = cmd->request_buffer;
669 memset(buf, 0, cmd->cmnd[4]); 663 memset(buf, 0, cmd->cmnd[4]);
670 if (cmd->use_sg) { 664 kunmap_atomic(buf - sg->offset, KM_IRQ0);
671 struct scatterlist *sg;
672 665
673 sg = (struct scatterlist *)cmd->request_buffer;
674 kunmap_atomic(buf - sg->offset, KM_IRQ0);
675 }
676 cmd->result = (DID_OK << 16); 666 cmd->result = (DID_OK << 16);
677 cmd->scsi_done(cmd); 667 cmd->scsi_done(cmd);
678 return NULL; 668 return NULL;
@@ -1551,23 +1541,15 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
1551 islogical = adapter->logdrv_chan[cmd->device->channel]; 1541 islogical = adapter->logdrv_chan[cmd->device->channel];
1552 if( cmd->cmnd[0] == INQUIRY && !islogical ) { 1542 if( cmd->cmnd[0] == INQUIRY && !islogical ) {
1553 1543
1554 if( cmd->use_sg ) { 1544 sgl = scsi_sglist(cmd);
1555 sgl = (struct scatterlist *) 1545 if( sgl->page ) {
1556 cmd->request_buffer; 1546 c = *(unsigned char *)
1557
1558 if( sgl->page ) {
1559 c = *(unsigned char *)
1560 page_address((&sgl[0])->page) + 1547 page_address((&sgl[0])->page) +
1561 (&sgl[0])->offset; 1548 (&sgl[0])->offset;
1562 } 1549 } else {
1563 else { 1550 printk(KERN_WARNING
1564 printk(KERN_WARNING 1551 "megaraid: invalid sg.\n");
1565 "megaraid: invalid sg.\n"); 1552 c = 0;
1566 c = 0;
1567 }
1568 }
1569 else {
1570 c = *(u8 *)cmd->request_buffer;
1571 } 1553 }
1572 1554
1573 if(IS_RAID_CH(adapter, cmd->device->channel) && 1555 if(IS_RAID_CH(adapter, cmd->device->channel) &&
@@ -1704,30 +1686,14 @@ mega_rundoneq (adapter_t *adapter)
1704static void 1686static void
1705mega_free_scb(adapter_t *adapter, scb_t *scb) 1687mega_free_scb(adapter_t *adapter, scb_t *scb)
1706{ 1688{
1707 unsigned long length;
1708
1709 switch( scb->dma_type ) { 1689 switch( scb->dma_type ) {
1710 1690
1711 case MEGA_DMA_TYPE_NONE: 1691 case MEGA_DMA_TYPE_NONE:
1712 break; 1692 break;
1713 1693
1714 case MEGA_BULK_DATA:
1715 if (scb->cmd->use_sg == 0)
1716 length = scb->cmd->request_bufflen;
1717 else {
1718 struct scatterlist *sgl =
1719 (struct scatterlist *)scb->cmd->request_buffer;
1720 length = sgl->length;
1721 }
1722 pci_unmap_page(adapter->dev, scb->dma_h_bulkdata,
1723 length, scb->dma_direction);
1724 break;
1725
1726 case MEGA_SGLIST: 1694 case MEGA_SGLIST:
1727 pci_unmap_sg(adapter->dev, scb->cmd->request_buffer, 1695 scsi_dma_unmap(scb->cmd);
1728 scb->cmd->use_sg, scb->dma_direction);
1729 break; 1696 break;
1730
1731 default: 1697 default:
1732 break; 1698 break;
1733 } 1699 }
@@ -1767,80 +1733,33 @@ __mega_busywait_mbox (adapter_t *adapter)
1767static int 1733static int
1768mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len) 1734mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
1769{ 1735{
1770 struct scatterlist *sgl; 1736 struct scatterlist *sg;
1771 struct page *page;
1772 unsigned long offset;
1773 unsigned int length;
1774 Scsi_Cmnd *cmd; 1737 Scsi_Cmnd *cmd;
1775 int sgcnt; 1738 int sgcnt;
1776 int idx; 1739 int idx;
1777 1740
1778 cmd = scb->cmd; 1741 cmd = scb->cmd;
1779 1742
1780 /* Scatter-gather not used */
1781 if( cmd->use_sg == 0 || (cmd->use_sg == 1 &&
1782 !adapter->has_64bit_addr)) {
1783
1784 if (cmd->use_sg == 0) {
1785 page = virt_to_page(cmd->request_buffer);
1786 offset = offset_in_page(cmd->request_buffer);
1787 length = cmd->request_bufflen;
1788 } else {
1789 sgl = (struct scatterlist *)cmd->request_buffer;
1790 page = sgl->page;
1791 offset = sgl->offset;
1792 length = sgl->length;
1793 }
1794
1795 scb->dma_h_bulkdata = pci_map_page(adapter->dev,
1796 page, offset,
1797 length,
1798 scb->dma_direction);
1799 scb->dma_type = MEGA_BULK_DATA;
1800
1801 /*
1802 * We need to handle special 64-bit commands that need a
1803 * minimum of 1 SG
1804 */
1805 if( adapter->has_64bit_addr ) {
1806 scb->sgl64[0].address = scb->dma_h_bulkdata;
1807 scb->sgl64[0].length = length;
1808 *buf = (u32)scb->sgl_dma_addr;
1809 *len = (u32)length;
1810 return 1;
1811 }
1812 else {
1813 *buf = (u32)scb->dma_h_bulkdata;
1814 *len = (u32)length;
1815 }
1816 return 0;
1817 }
1818
1819 sgl = (struct scatterlist *)cmd->request_buffer;
1820
1821 /* 1743 /*
1822 * Copy Scatter-Gather list info into controller structure. 1744 * Copy Scatter-Gather list info into controller structure.
1823 * 1745 *
1824 * The number of sg elements returned must not exceed our limit 1746 * The number of sg elements returned must not exceed our limit
1825 */ 1747 */
1826 sgcnt = pci_map_sg(adapter->dev, sgl, cmd->use_sg, 1748 sgcnt = scsi_dma_map(cmd);
1827 scb->dma_direction);
1828 1749
1829 scb->dma_type = MEGA_SGLIST; 1750 scb->dma_type = MEGA_SGLIST;
1830 1751
1831 BUG_ON(sgcnt > adapter->sglen); 1752 BUG_ON(sgcnt > adapter->sglen || sgcnt < 0);
1832 1753
1833 *len = 0; 1754 *len = 0;
1834 1755
1835 for( idx = 0; idx < sgcnt; idx++, sgl++ ) { 1756 scsi_for_each_sg(cmd, sg, sgcnt, idx) {
1836 1757 if (adapter->has_64bit_addr) {
1837 if( adapter->has_64bit_addr ) { 1758 scb->sgl64[idx].address = sg_dma_address(sg);
1838 scb->sgl64[idx].address = sg_dma_address(sgl); 1759 *len += scb->sgl64[idx].length = sg_dma_len(sg);
1839 *len += scb->sgl64[idx].length = sg_dma_len(sgl); 1760 } else {
1840 } 1761 scb->sgl[idx].address = sg_dma_address(sg);
1841 else { 1762 *len += scb->sgl[idx].length = sg_dma_len(sg);
1842 scb->sgl[idx].address = sg_dma_address(sgl);
1843 *len += scb->sgl[idx].length = sg_dma_len(sgl);
1844 } 1763 }
1845 } 1764 }
1846 1765
@@ -3571,7 +3490,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
3571 /* 3490 /*
3572 * The user passthru structure 3491 * The user passthru structure
3573 */ 3492 */
3574 upthru = (mega_passthru __user *)MBOX(uioc)->xferaddr; 3493 upthru = (mega_passthru __user *)(unsigned long)MBOX(uioc)->xferaddr;
3575 3494
3576 /* 3495 /*
3577 * Copy in the user passthru here. 3496 * Copy in the user passthru here.
@@ -3623,7 +3542,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
3623 /* 3542 /*
3624 * Get the user data 3543 * Get the user data
3625 */ 3544 */
3626 if( copy_from_user(data, (char __user *)uxferaddr, 3545 if( copy_from_user(data, (char __user *)(unsigned long) uxferaddr,
3627 pthru->dataxferlen) ) { 3546 pthru->dataxferlen) ) {
3628 rval = (-EFAULT); 3547 rval = (-EFAULT);
3629 goto freemem_and_return; 3548 goto freemem_and_return;
@@ -3649,7 +3568,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
3649 * Is data going up-stream 3568 * Is data going up-stream
3650 */ 3569 */
3651 if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) { 3570 if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) {
3652 if( copy_to_user((char __user *)uxferaddr, data, 3571 if( copy_to_user((char __user *)(unsigned long) uxferaddr, data,
3653 pthru->dataxferlen) ) { 3572 pthru->dataxferlen) ) {
3654 rval = (-EFAULT); 3573 rval = (-EFAULT);
3655 } 3574 }
@@ -3702,7 +3621,7 @@ freemem_and_return:
3702 /* 3621 /*
3703 * Get the user data 3622 * Get the user data
3704 */ 3623 */
3705 if( copy_from_user(data, (char __user *)uxferaddr, 3624 if( copy_from_user(data, (char __user *)(unsigned long) uxferaddr,
3706 uioc.xferlen) ) { 3625 uioc.xferlen) ) {
3707 3626
3708 pci_free_consistent(pdev, 3627 pci_free_consistent(pdev,
@@ -3742,7 +3661,7 @@ freemem_and_return:
3742 * Is data going up-stream 3661 * Is data going up-stream
3743 */ 3662 */
3744 if( uioc.xferlen && (uioc.flags & UIOC_RD) ) { 3663 if( uioc.xferlen && (uioc.flags & UIOC_RD) ) {
3745 if( copy_to_user((char __user *)uxferaddr, data, 3664 if( copy_to_user((char __user *)(unsigned long) uxferaddr, data,
3746 uioc.xferlen) ) { 3665 uioc.xferlen) ) {
3747 3666
3748 rval = (-EFAULT); 3667 rval = (-EFAULT);
@@ -4494,7 +4413,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
4494 scmd->device = sdev; 4413 scmd->device = sdev;
4495 4414
4496 scmd->device->host = adapter->host; 4415 scmd->device->host = adapter->host;
4497 scmd->request_buffer = (void *)scb; 4416 scmd->host_scribble = (void *)scb;
4498 scmd->cmnd[0] = MEGA_INTERNAL_CMD; 4417 scmd->cmnd[0] = MEGA_INTERNAL_CMD;
4499 4418
4500 scb->state |= SCB_ACTIVE; 4419 scb->state |= SCB_ACTIVE;